suoi21 高能显示屏 (cdq分治)

可以把翻倍的操作看作是一个查询和修改(增加刚查询得来的值)的符合操作,然后做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 }
原文地址:https://www.cnblogs.com/Ressed/p/9696154.html