hdu 4288 (成都赛区2012网络赛)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 #define mid (l+r)>>1
10 #define ls rt<<1
11 #define rs rt<<1|1
12 #define lson l,m,rt<<1
13 #define rson m+1,r,rt<<1|1
14 
15 #define MAXN 100010
16 int sum[MAXN<<2]; //区间的元素个数
17 __int64 ans[MAXN<<2][5];//分别表示mod5
18 int key[MAXN];//离散化用
19 int x[MAXN];
20 
21 char op[MAXN][10];
22 
23 void pushup(int rt)
24 {
25     for(int i=0;i<5;i++)
26     {
27         ans[rt][i]=ans[ls][i]+ans[rs][(i-sum[ls]%5+5)%5];
28     }
29 }
30 
31 void build(int l,int r,int rt)
32 {
33     sum[rt]=0;
34     memset(ans[rt],0,sizeof(ans[rt]));
35     if(l==r)   
36         return;
37     int m = mid;
38     build(lson);  
39     build(rson);
40 }
41 
42 int flag;//判断用
43 void update(int p,int l,int r,int rt)
44 {
45     sum[rt]+=2*flag-1;
46     if (l==r)    
47     {
48         ans[rt][1]=flag*key[p];//叶子节点的值mod5肯定为1
49         return ;
50     }
51     int m=mid;
52     if (p<= m)       
53         update(p,lson);
54     else    
55         update(p,rson);
56     pushup(rt);     
57 }
58 
59 int main()
60 {
61     int n,tot=0;
62     while(scanf("%d",&n) != EOF)
63     {
64         tot=0;
65         for(int i=0;i<n;i++)
66         {    
67             scanf("%s",op[i]);
68             if(op[i][0]=='a' || op[i][0]=='d')
69             {    
70                 scanf("%d",&x[i]);
71                 key[tot++]=x[i];
72             }
73         }
74         sort(key,key+tot);
75         tot = unique(key,key+tot) - key;
76         build(1,tot,1);
77         for(int i=0;i<n;i++)
78         {
79             int pos = lower_bound(key,key+tot,x[i]) - key;
80             if(op[i][0] == 's')
81                 printf("%I64d\n",ans[1][3]);
82             else
83             {
84                 if(op[i][0]=='a')
85                     flag=1;
86                 else
87                     flag=0;
88                 update(pos,1,tot,1);
89             }
90         }
91     }
92     return 0;
93 }

线段树   + 离散化 :

这题是codeforce上的原题。。。o(︶︿︶)o 唉。

用ans[][5]分别表示区间内mod5==i的五种情况的和。比如ans[][2]==4,表示这个区间内下表mod5==2的值的和为4.

假如我们 求  i ==  3 时 (表示  %5 == 3)

对于左子树我们直接求就可以 ,但是对于右子树,我们要知道 在 i== 3 的 情况下 ,右子树的元素的下标应该是 %5 == 几?

ans[rt][i]=ans[ls][i]+ans[rs][(i-sum[ls]%5+5)%5];

 

原文地址:https://www.cnblogs.com/Missa/p/2697666.html