http://codeforces.com/problemset/problem/85/D
http://acm.hdu.edu.cn/showproblem.php?pid=4288
其实就是五棵线段树,我把它放在同一个数组里了,这样比较好处理,其中因为没有处理取模时会有负数的情况,最后让它加上一个很大的数才过的。(i+c+100000)%5
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define maxn 100005 7 #define ll __int64 8 struct node{ 9 ll sum[5]; 10 int cnt,numpos; 11 }setree[maxn<<2]; 12 struct { 13 ll num; 14 char s[5]; 15 }mes[maxn]; 16 ll sorted[maxn]; 17 void build(int l,int r,int rt) 18 { 19 for(int i=0;i<5;i++) 20 setree[rt].sum[i]=0; 21 setree[rt].cnt=0; 22 setree[rt].numpos=0; 23 if(l==r) 24 return; 25 int m=(l+r)>>1; 26 build(lson); 27 build(rson); 28 } 29 void pushup(int rt) 30 { 31 for(int i=0;i<5;i++) 32 setree[rt].sum[i]=setree[rt<<1].sum[i]+setree[rt<<1|1].sum[i]; 33 setree[rt].numpos=setree[rt<<1].numpos+setree[rt<<1|1].numpos; 34 } 35 int binsearch(int l,int r,ll num) 36 { 37 int m=(l+r)>>1; 38 if(sorted[m]==num) 39 return m; 40 if(num<sorted[m]) 41 return binsearch(l,m-1,num); 42 return binsearch(m+1,r,num); 43 } 44 void pushdown(int rt) 45 { 46 ll tmp[5]; 47 if(setree[rt].cnt!=0){ 48 int c=setree[rt].cnt; 49 if(setree[rt<<1].numpos!=0){ 50 setree[rt<<1].cnt+=c; 51 for(int i=0;i<5;i++) 52 tmp[i]=setree[rt<<1].sum[i]; 53 for(int i=0;i<5;i++) 54 setree[rt<<1].sum[i]=tmp[(i+c+100000)%5]; 55 } 56 if(setree[rt<<1|1].numpos!=0){ 57 setree[rt<<1|1].cnt+=c; 58 for(int i=0;i<5;i++) 59 tmp[i]=setree[rt<<1|1].sum[i]; 60 for(int i=0;i<5;i++) 61 setree[rt<<1|1].sum[i]=tmp[(i+c+100000)%5]; 62 } 63 setree[rt].cnt=0; 64 } 65 } 66 void update1(int l,int r,int rt,int num,int pos) 67 { 68 if(l==r){ 69 setree[rt].sum[pos%5]=sorted[num]; 70 setree[rt].numpos=1; 71 return; 72 } 73 pushdown(rt); 74 int m=(l+r)>>1; 75 if(num<=m) 76 update1(lson,num,pos); 77 else 78 update1(rson,num,pos); 79 pushup(rt); 80 } 81 int query(int l,int r,int rt,int L,int R) 82 { 83 if(L>R) 84 return 0; 85 if(L<=l&&r<=R) 86 return setree[rt].numpos; 87 int m=(l+r)>>1; 88 int ans=0; 89 if(L<=m) 90 ans+=query(lson,L,R); 91 if(R>m) 92 ans+=query(rson,L,R); 93 return ans; 94 } 95 void update2(int l,int r,int rt,int num) 96 { 97 if(l==r){ 98 for(int i=0;i<5;i++) 99 setree[rt].sum[i]=0; 100 setree[rt].numpos=0; 101 setree[rt].cnt=0; 102 return; 103 } 104 pushdown(rt); 105 int m=(l+r)>>1; 106 if(num<=m) 107 update2(lson,num); 108 else 109 update2(rson,num); 110 pushup(rt); 111 } 112 void update3(int l,int r,int rt,int L,int R,int c) 113 { 114 if(L<=l&&r<=R){ 115 ll tmp[5]; 116 setree[rt].cnt+=c; 117 for(int i=0;i<5;i++) 118 tmp[i]=setree[rt].sum[i]; 119 for(int i=0;i<5;i++) 120 setree[rt].sum[i]=tmp[(i+c+100000)%5]; 121 return; 122 } 123 pushdown(rt); 124 int m=(l+r)>>1; 125 if(L<=m) 126 update3(lson,L,R,c); 127 if(R>m) 128 update3(rson,L,R,c); 129 pushup(rt); 130 } 131 int main() 132 { 133 int m; 134 while(~scanf("%d",&m)){ 135 int n=0; 136 for(int i=1;i<=m;i++){ 137 scanf("%s",&mes[i].s); 138 if(mes[i].s[0]=='a'||mes[i].s[0]=='d'){ 139 scanf("%I64d",&mes[i].num); 140 sorted[++n]=mes[i].num; 141 } 142 } 143 sort(sorted+1,sorted+n+1); 144 int k=1; 145 for(int i=2;i<=n;i++) 146 if(sorted[i]!=sorted[i-1]) 147 sorted[++k]=sorted[i]; 148 build(1,k,1); 149 for(int i=1;i<=m;i++){ 150 if(mes[i].s[0]=='a'){ 151 int pos=binsearch(1,k,mes[i].num); 152 int c=query(1,k,1,1,pos-1); 153 int cc=query(1,k,1,pos+1,k); 154 update1(1,k,1,pos,c+1); 155 if(cc!=0) 156 update3(1,k,1,pos+1,k,-1); 157 } 158 else if(mes[i].s[0]=='d'){ 159 int pos=binsearch(1,k,mes[i].num); 160 update2(1,k,1,pos); 161 int cc=query(1,k,1,pos+1,k); 162 if(cc!=0) 163 update3(1,k,1,pos+1,k,1); 164 } 165 else 166 printf("%I64d\n",setree[1].sum[3]); 167 } 168 } 169 return 0; 170 }
膜拜各路神牛教主,用了几乎我3分之一的代码量就过了。