可以把翻倍的操作看作是一个查询和修改(增加刚查询得来的值)的符合操作,然后做cdq就行了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=200010; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 struct Node{ 22 int x,y,tp,id; 23 }op[maxn]; 24 int N,M,rg[maxn],tmp[maxn]; 25 ll tr[maxn],ans[maxn]; 26 27 inline void add(int x,ll y){ 28 for(;x<=M;x+=lowb(x)) tr[x]+=y; 29 } 30 inline ll query(int x){ 31 ll re=0;for(;x;x-=lowb(x)) re+=tr[x];return re; 32 } 33 34 inline bool cmp(int a,int b){ 35 return op[a].x<op[b].x; 36 } 37 38 void cdq(int l,int r){ 39 if(l>=r) return; 40 // printf("!%d %d ",l,r); 41 int m=(l+r)>>1; 42 cdq(l,m); 43 memcpy(tmp+l,rg+l,4*(r-l+1)); 44 sort(tmp+l,tmp+m+1,cmp);sort(tmp+m+1,tmp+r+1,cmp); 45 int p=l,q=m+1; 46 for(;q<=r&&op[tmp[q]].x<op[tmp[l]].x;q++); 47 for(;q<=r;p++){ 48 // printf("%d %d ",p,q); 49 Node a=op[tmp[p]]; 50 if(a.tp==2) 51 add(a.y,1); 52 else if(a.tp==3) 53 add(a.y,ans[a.id]); 54 for(int i=q;i<=r&&op[tmp[i]].x==a.x;i++){ 55 if(op[tmp[i]].y==a.y&&op[tmp[i]].tp==3){ 56 // printf("!!%d ",tmp[i]); 57 if(a.tp==2) ans[op[tmp[i]].id]++; 58 else if(a.tp==3) ans[op[tmp[i]].id]+=ans[a.id]; 59 } 60 } 61 for(;q<=r&&(p==m||op[tmp[q]].x<op[tmp[p+1]].x);q++){ 62 // printf("%d ",q); 63 if(op[tmp[q]].tp==1){ 64 ans[op[tmp[q]].id]+=query(op[tmp[q]].y); 65 } 66 } 67 } 68 p--; 69 while(p>=l){ 70 Node a=op[tmp[p--]]; 71 if(a.tp==2) 72 add(a.y,-1); 73 else if(a.tp==3) 74 add(a.y,-ans[a.id]); 75 } 76 cdq(m+1,r); 77 } 78 79 int main(){ 80 freopen("21.in","r",stdin); 81 freopen("21.txt","w",stdout); 82 rei i; 83 N=rd(); 84 for(i=1;i<=N;i++){ 85 char s[5]; 86 scanf("%s",s); 87 if(s[0]=='Q') op[i].tp=1; 88 else if(s[0]=='A') op[i].tp=2; 89 else op[i].tp=3; 90 op[i].x=rd(),op[i].y=rd(),op[i].id=i; 91 M=max(M,op[i].y); 92 rg[i]=i; 93 } 94 cdq(1,N); 95 for(i=1;i<=N;i++) if(op[i].tp==1) printf("%lld ",ans[i]); 96 return 0; 97 }