【樹狀陣列套線段樹】數列
阿新 • • 發佈:2019-02-03
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for (int i = a;i <= b;i ++) using namespace std; const int maxn = 120005; const int lim = 120000; const int low = -100000; const int high = 60000; const int maxm = 7000005; int A[maxn],left[maxm],right[maxm],tree[maxm]; int root[maxn]; int N,Q,tot; inline void Insert(int &z,int l,int r,int p) { if (!z) z = ++ tot; if (l == r) { tree[z] ++; return; } int mid = (l + r) >> 1; if (p <= mid) Insert(left[z],l,mid,p); else Insert(right[z],mid+1,r,p); tree[z] = tree[left[z]] + tree[right[z]]; } inline int lowbit(int x) { return (x & (-x)); } void Ins(int x,int y) { while (x <= lim) { Insert(root[x],low,high,y); x += lowbit(x); } } inline int Query(int z,int l,int r,int x,int y) { if (!z) return 0; if (x <= l && r <= y) return tree[z]; int ret = 0; int mid = (l + r) >> 1; if (x <= mid) ret += Query(left[z],l,mid,x,y); if (y > mid) ret += Query(right[z],mid+1,r,x,y); return ret; } int Que(int x,int l,int r) { int ret = 0; l = max(l,low); r = min(r,high); while (x) { ret += Query(root[x],low,high,l,r); x -= lowbit(x); } return ret; } int main() { scanf("%d%d",&N,&Q); fo(i,1,N) scanf("%d",&A[i]); fo(i,1,N) Ins(i+A[i],i-A[i]); fo(cas,1,Q) { char op[10]; int x,k; scanf("%s",op); scanf("%d%d",&x,&k); if (op[0] == 'Q') { int ans = Que(min(x+A[x]+k,lim),x-A[x]-k,x-A[x]+k) - Que(max(min(x+A[x]-k-1,lim),0),x-A[x]-k,x-A[x]+k); printf("%d\n",ans); } else { A[x] = k; Ins(x+A[x],x-A[x]); } } return 0; }