HDU - 6534 Chika and Friendly Pairs(樹狀陣列+莫隊)
阿新 • • 發佈:2021-07-21
題目大意
詢問區間[l,r]中滿足相鄰兩個樹大小不超過k的數對。
解題思路
如果一個一個加入數字的話,設當前數字為i,那麼對答案的貢獻就是之前的數字之中\([a_i-k,a_i+k]\)範圍內的數字的數量,可以用莫隊來維護l,r,然後每次的修改和查詢操作用樹狀陣列來操作。
程式碼
const int maxn = 1e5+10; const int maxm = 1e6+10; int n, nn, m, k; int a[maxn], b[maxn], p[maxn]; int find(int x) { return lower_bound(b+1, b+nn+1, x)-b; } int find2(int x) { return upper_bound(b+1, b+nn+1, x)-b; } int c[maxn]; void insert(int x, int y) { while(x<=n) { c[x] += y; x += x&-x; } } int ask(int x) { int sum = 0; while(x) { sum += c[x]; x -= x&-x; } return sum; } struct Q { int l, r, i; } q[maxn]; int l = 1, r = 0; int ans[maxn], res, up[maxn], low[maxn]; void add(int x) { res += ask(up[x])-ask(low[x]-1); insert(a[x], 1); } void sub(int x) { insert(a[x], -1); res -= ask(up[x])-ask(low[x]-1); //cout << a[x] << ' ' << l << ' ' << r << ' ' << res << endl; } int main() { IOS; cin >> n >> m >> k; for (int i = 1; i<=n; ++i) cin >> a[i], b[i] = a[i]; sort(b+1, b+n+1); nn = unique(b+1, b+n+1)-b-1; for (int i = 1; i<=n; ++i) { low[i] = find(a[i]-k); up[i] = find2(a[i]+k)-1; a[i] = find(a[i]); //cout << low[i] << ' ' << a[i] << ' ' << up[i] << endl; } for (int i = 1; i<=m; ++i) { cin >> q[i].l >> q[i].r; q[i].i = i; } int sz = sqrt(m)+1; sort(q+1, q+m+1, [=](Q x, Q y) {return (x.l/sz^y.l/sz) ? x.l/sz<y.l/sz : ((x.l/sz)%2 ? x.r<y.r:x.r>y.r);}); for (int i = 1; i<=m; ++i) { //cout << q[i].l << ' ' << q[i].r << endl; while(q[i].r > r) add(++r); //cout << res << endl; while(q[i].l > l) sub(l++); //cout << res << endl; while(q[i].r < r) sub(r--); //cout << res << endl; while(q[i].l < l) add(--l); //cout << res << endl; ans[q[i].i] = res; } for (int i = 1; i<=m; ++i) cout << ans[i] << endl; return 0; }