比赛的时候一直想的主席树,维护的复杂度已经够了,但是插入又不对了。
最后就卡死了。
莫队老是想不到,太菜了。
正解:莫队离线一下询问。我们从左向右维护点的值。
那么加上每个点的代价,查询一下区间内[a[i] - k,a[i] + k]的个数即可。
减去每个点同理,但是因为自己也会被算在内。所以减去的时候,要先删掉自己的值再算,因为我们加上的时候其实是没有算上自己的代价的。
然后这题线段树会T,所以要树状数组维护区间和。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; const int N = 27005; const int M = 2e5 + 5; const double eps = 1e-10; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; inline int read() { int f = 1;int x = 0;char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} int a[N],b[N * 3],ans[N],len = 0,k,L[N],r[N],ps[N],n; struct Query{int L,r,bl,id;}p[N]; LL ma = 0; bool cmp(Query a,Query b) { if(a.bl != b.bl) return a.L < b.L; if(a.bl&1) return a.r < b.r; return a.r > b.r; } int lowbit(int x) {return x & (-x);} int sum[N * 3]; void add_num(int x,int val) { for(int i = x;i <= len;i += lowbit(i)) sum[i] += val; } int query2(int x) { int tmp = 0; for(int i = x;i;i -= lowbit(i)) tmp += sum[i]; return tmp; } int query(int L,int r) { return query2(r) - query2(L - 1); } void del(int x) { add_num(ps[x],-1); int sum = query(L[x],r[x]); ma -= sum; } void add(int x) { int sum = query(L[x],r[x]); ma += sum; add_num(ps[x],1); } void solve() { int m;n = read(),m = read(),k = read(); for(int i = 1;i <= n;++i) { a[i] = read(); b[++len] = a[i] + k; b[++len] = a[i] - k; b[++len] = a[i]; } sort(b + 1,b + len + 1); len = unique(b + 1,b + len + 1) - b - 1; for(int i = 1;i <= n;++i) { L[i] = lower_bound(b + 1,b + len + 1,a[i] - k) - b; r[i] = lower_bound(b + 1,b + len + 1,a[i] + k) - b; ps[i] = lower_bound(b + 1,b + len + 1,a[i]) - b; } int blsize = sqrt(n); for(int i = 1;i <= m;++i) p[i].L = read(),p[i].r = read(),p[i].id = i,p[i].bl = (p[i].L - 1) / blsize + 1; sort(p + 1,p + m + 1,cmp); int L = 1,r = 0; for(int i = 1;i <= m;++i) { while(L < p[i].L) del(L++); while(L > p[i].L) add(--L); while(r < p[i].r) add(++r); while(r > p[i].r) del(r--); ans[p[i].id] = ma; } for(int i = 1;i <= m;++i) printf("%d\n",ans[i]); } int main() { solve(); system("pause"); return 0; }View Code