1. 程式人生 > >51nod 1290 Counting Diff Pairs | 莫隊 樹狀數組

51nod 1290 Counting Diff Pairs | 莫隊 樹狀數組

clu tchar bool using mod per include for line

51nod 1290 Counting Diff Pairs | 莫隊 樹狀數組

題面

一個長度為N的正整數數組A,給出一個數K以及Q個查詢,每個查詢包含2個數l和r,對於每個查詢輸出從A[i]到A[j]中,有多少對數,abs(A[i] - A[j]) <= K(abs表示絕對值)。

題解

莫隊!//其實我就是搜索“51nod + 莫隊”找到的這道題……
七級算法題!
一道320分!
你值得擁有!

題解就是……用個普通的莫隊,加上樹狀數組來統計符合條件的數個數,就好啦。
當增加/刪除一個數的時候,統計能和它組成合法數對的數的個數,然後對答案進行相應的增/減。

#include <cstdio>
#include <cmath> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; template <class T> void read(T &x){ char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'
; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x){ if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } #define space putchar(' ')
#define enter putchar('\n') const int N = 50005, B = 233; int n, d, m, a[N], lst[N], idx, tol[N], tor[N], tr[N], pl = 1, pr; ll res, ans[N]; #define bel(x) (((x) - 1) / B + 1) struct query { int id, l, r; bool operator < (const query &b) const { return bel(l) == bel(b.l) ? r < b.r : l < b.l; } } q[N]; void init(){ sort(lst + 1, lst + n + 1); idx = unique(lst + 1, lst + n + 1) - lst - 1; for(int i = 1; i <= n; i++) a[i] = lower_bound(lst + 1, lst + idx + 1, a[i]) - lst; int l = 1, r = 1; for(int i = 1; i <= idx; i++){ while(l < i && lst[i] - lst[l] > d) l++; while(r < idx && lst[r + 1] - lst[i] <= d) r++; tol[i] = l, tor[i] = r; } } void add(int p, int x){ while(p <= idx) tr[p] += x, p += p & -p; } int ask(int p){ int res = 0; while(p) res += tr[p], p -= p & -p; return res; } int getres(int x){ return ask(tor[x]) - ask(tol[x] - 1); } int main(){ read(n), read(d), read(m); for(int i = 1; i <= n; i++) read(a[i]), lst[i] = a[i]; init(); for(int i = 1; i <= m; i++) q[i].id = i, read(q[i].l), q[i].l++, read(q[i].r), q[i].r++; sort(q + 1, q + m + 1); for(int i = 1; i <= m; i++){ while(pl > q[i].l) res += getres(a[--pl]), add(a[pl], 1); while(pr < q[i].r) res += getres(a[++pr]), add(a[pr], 1); while(pl < q[i].l) add(a[pl], -1), res -= getres(a[pl++]); while(pr > q[i].r) add(a[pr], -1), res -= getres(a[pr--]); ans[q[i].id] = res; } for(int i = 1; i <= m; i++) write(ans[i]), enter; return 0; }

51nod 1290 Counting Diff Pairs | 莫隊 樹狀數組