离线做法:分别处理每个编号上的各种询问和操作,接着就能用树状数组维护。
#include <cstdlib> #include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <iostream> #define rep(i, l, r) for(int i=l; i<=r; i++) #define clr(x, c) memset(x, c, sizeof(x)) #define lowbit(x) (x&-x) #define maxn 123456 #define s(x) Size[x] #define k(x) Key[x] using namespace std; inline int read() { int x=0, f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*f; } struct node{int x, y, k, type, q;} q[maxn*4]; bool cmp(node a, node b){return a.k<b.k || (a.k==b.k && a.q<b.q);} int n, m, ans[maxn*4], Key[maxn*4], Size[maxn*4], tot; inline void Add(int x, int k){while (x<=n) s(x)+=k, x+=lowbit(x);} inline int Query(int x){int now=0; while (x>0) now+=s(x), x-=lowbit(x); return now;} int main() { n=read(), m=read(); rep(i, 1, n) q[++tot]=(node){i, 1, k(i)=read(), 0, tot}; char ch[5]; rep(i, 1, m) { scanf("%s", ch); int x=read(), y=read(); if (ch[0]=='C') q[++tot]=(node){x, -1, k(x), 0, tot}, q[++tot]=(node){x, 1, k(x)=y, 0, tot}; else q[++tot]=(node){x, y, read(), 1, tot}; } rep(i, 1, tot) ans[i]=-1; sort(q+1, q+1+tot, cmp); int s=1; rep(t, 1, tot) { if (q[t].k==q[t+1].k) continue; clr(Size, 0); rep(i, s, t) if (!q[i].type) Add(q[i].x, q[i].y); else ans[q[i].q]=Query(q[i].y)-Query(q[i].x-1); s=t+1; } rep(i, 1, tot) if (ans[i]!=-1) printf("%d ", ans[i]); }