扫描线 + BIT + 离线 0pts 求调
查看原帖
扫描线 + BIT + 离线 0pts 求调
534562
liheyang123楼主2025/8/4 14:42

rt,样例已过,原数据全 WA,hack RE ::::info[code(有注释)]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> PII;
#define int ll

inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch - '0'); ch = getchar(); }
	return x * f;
}

const int N = 3e5 + 10;
int n, m, tr[N]; 
struct NODE{
	int x, id;
	bool operator < (const NODE&rhs){return x < rhs.x;};
}a[N]; // 根据全职排序 
struct Match{
	int x, y;
	Match(int _x, int _y) {x = _x, y = _y;}
	bool operator < (const Match&rhs) {return x < rhs.x;}
}; vector<Match> v; // 配对 (x,y) 且 x < y,(x,y) <=> (y,x),所以只记录一次 
struct Query{
	int x, y, id;
	bool operator < (const Query&rhs){
		if(x == rhs.x) return y < rhs.y;
		return x < rhs.x;
	};
}q[N]; // 询问 

void add(int x, int v){if(x == 0) return; for(; x <= n; x += (x & -x)) tr[x] += v;}
int query(int x){int res = 0; for(; x; x -= (x & -x)) res += tr[x]; return res;}

signed main(){
	n = read(), m = read();
	for(int i = 1; i <= n; i++) {a[i].x = read(), a[i].id = i;}
	for(int i = 1; i <= m; i++){
		q[i].x = read(), q[i].y = read();
		q[i].id = i;
	}
	sort(a + 1, a + 1 + n), sort(q + 1, q + 1 + m);
	a[n + 1].x = 1e9;
	for(int i = 2; i <= n; i++)
		if(a[i].x - a[i - 1].x <= a[i + 1].x - a[i].x){
			add(a[i].id, 2); //(x,y) 同时表示 (x,y)、(y,x) 所以值的贡献是 2 
			int mn =  min(a[i - 1].id, a[i].id),
				mx = max(a[i - 1].id, a[i].id);
			v.push_back(Match(mn, mx));
		} // 求出所有 (x,y),(x,y) <=> (y,x),所以只记录一次 
	// 一维按照顺序处理,另一位树状数组处理 
	sort(v.begin(), v.end());
	int pos = 0, ans = 0;
	for(int i = 1; i <= m; i++){
		while(v[pos].x < q[i].x && pos < v.size()) 
			add(v[pos].y, -2), pos++;
		// 删去左端点出界的配对,求所有右端点小于 q[i].y 的值 
		ans += (query(q[i].y) * q[i].id);
	} printf("%d\n", ans);
	return 0;
}

::::

2025/8/4 14:42
加载中...