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;
}
::::