首页 > 代码库 > Coder(线段树)

Coder(线段树)

求一部分和的线段树,因为是对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 }
View Code