求一部分和的线段树,因为是对5取余,所以给定一段区间a-b,假设其位置会有变化,最多会有5种和,那么就可以保留这五种和,在用lz进行延迟标记时,保存位置变化了多少也就知道了该从当前和转到哪一个和。
当时把lz标记那么部分写成覆盖了,应该是+=,WA了两次。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 #include<map> 11 using namespace std; 12 #define N 100010 13 #define LL __int64 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 map<int,int>f; 19 LL s[N<<2][5]; 20 int lz[N<<2],fg[N<<2],a[N]; 21 struct node 22 { 23 int x; 24 char sr[20]; 25 }p[N]; 26 void up(int w) 27 { 28 int i; 29 for(i = 0; i < 5 ; i++) 30 s[w][i] = s[w<<1][i]+s[w<<1|1][i]; 31 fg[w] = fg[w<<1]+fg[w<<1|1]; 32 } 33 void down(int w,int m) 34 { 35 int i; 36 if(lz[w]) 37 { 38 lz[w<<1] += lz[w]; 39 lz[w<<1|1] += lz[w]; 40 LL x[5],y[5]; 41 for(i = 0 ;i < 5 ; i++) 42 { 43 x[i] = s[w<<1][i]; 44 y[i] = s[w<<1|1][i]; 45 } 46 for(i =0 ; i < 5 ; i++) 47 { 48 s[w<<1][(i+lz[w]%5+5)%5] = x[i]; 49 s[w<<1|1][(i+lz[w]%5+5)%5] = y[i]; 50 } 51 lz[w] = 0; 52 } 53 } 54 void build(int l,int r,int w) 55 { 56 if(l==r) 57 { 58 for(int i = 0 ;i < 5 ; i++) 59 { 60 s[w][i] = 0; 61 } 62 fg[w] = 0; 63 return ; 64 } 65 int m = (l+r)>>1; 66 build(l,m,w<<1); 67 build(m+1,r,w<<1|1); 68 up(w); 69 } 70 void update(int a,int b,int d,int l,int r,int w) 71 { 72 if(a<=l&&b>=r) 73 { 74 int i; 75 LL x[5]; 76 for(i = 0 ; i < 5 ; i++) 77 { 78 x[i] = s[w][i]; 79 } 80 for(i = 0 ; i < 5 ; i++) 81 s[w][(i+d+5)%5] = x[i]; 82 lz[w] += d; 83 return ; 84 } 85 down(w,r-l+1); 86 int m = (l+r)>>1; 87 if(a<=m) update(a,b,d,l,m,w<<1); 88 if(b>m) update(a,b,d,m+1,r,w<<1|1); 89 up(w); 90 } 91 void add(int p,int d,int po,int flag,int l,int r,int w) 92 { 93 if(l==r) 94 { 95 int i; 96 if(flag) 97 { 98 for(i = 0 ; i < 5 ; i++) 99 if((po+1)%5==i) 100 { 101 s[w][i] = d; 102 //if(d==4) cout<<i<<endl; 103 } 104 else s[w][i] = 0; 105 fg[w] = 1; 106 } 107 else 108 { 109 for(i = 0; i< 5 ; i++) 110 s[w][i] = 0; 111 fg[w] = 0; 112 } 113 return ; 114 } 115 down(w,r-l+1); 116 int m = (l+r)>>1; 117 if(p<=m) add(p,d,po,flag,l,m,w<<1); 118 else add(p,d,po,flag,m+1,r,w<<1|1); 119 up(w); 120 } 121 int query(int a,int b,int l,int r,int w) 122 { 123 if(a<=l&&b>=r) 124 return fg[w]; 125 int m = (l+r)>>1; 126 int res = 0; 127 down(w,r-l+1); 128 if(a<=m) 129 res+=query(a,b,l,m,w<<1); 130 if(b>m) 131 res+=query(a,b,m+1,r,w<<1|1); 132 return res; 133 } 134 int main() 135 { 136 int n,i; 137 while(scanf("%d",&n)!=EOF) 138 { 139 memset(lz,0,sizeof(lz)); 140 f.clear(); 141 int g = 0; 142 for(i = 1; i <= n ;i++) 143 { 144 scanf("%s",p[i].sr); 145 if(p[i].sr[0]==‘s‘) continue; 146 scanf("%d",&p[i].x); 147 a[++g] = p[i].x; 148 } 149 sort(a+1,a+g+1); 150 int o = 1; 151 f[a[1]] = 1; 152 for(i = 2; i <= g; i++) 153 if(a[i]!=a[i-1]) 154 f[a[i]] = ++o; 155 build(1,o,1); 156 for(i = 1; i <= n ;i++) 157 { 158 if(p[i].sr[0]==‘a‘) 159 { 160 int k = query(1,f[p[i].x],1,o,1); 161 add(f[p[i].x],p[i].x,k,1,1,o,1); 162 if(f[p[i].x]<o) 163 update(f[p[i].x]+1,o,1,1,o,1); 164 } 165 else if(p[i].sr[0]==‘d‘) 166 { 167 //int k = query(1,f[p[i].x],1,o,1); 168 add(f[p[i].x],p[i].x,0,0,1,o,1); 169 if(f[p[i].x]<o) 170 update(f[p[i].x]+1,o,-1,1,o,1); 171 172 }else 173 printf("%I64d\n",s[1][3]); 174 } 175 } 176 return 0; 177 }
原文地址:http://www.cnblogs.com/shangyu/p/3765146.html