Coder

hdu4288:http://acm.hdu.edu.cn/showproblem.php?pid=4288

题意:有三种类型的操作,(1)."add x",表示往集合里添加数x。(2).“del x”表示将集合中数x删除。(3).“sum”求出从小到大排列的集合中下标模5为3的数的和。集合中的数都是唯一的。

题解:线段树离线操作,一开始没有想到,看了别人的思路才知道用线段树怎么操作。用5个线段树分别维护:下标取模分别为0 1 2 3 4的数的和。对于一棵树的来说,该区间的sum【u】【i】=sum【u<<1】[i],同时,对于幼儿来说,sum【u<<1|1】【i】应该贡献给父亲sum[u][(i+id)%5],id为左子树的个数。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define lson u<<1
 6 #define  rson u<<1|1
 7 using namespace std;
 8 const int N=100003;
 9 long long sum[4*N][5],a[N],idx[N];
10 int ll[4*N],rr[4*N],num[4*N],top;
11 char op[N][20];
12 int n;
13 void pushUP(int u){
14     num[u]=num[lson]+num[rson];
15     int id=num[lson];
16     for(int i=0;i<=4;i++){
17         sum[u][i]=sum[lson][i];
18     }
19     for(int i=0;i<=4;i++){
20         sum[u][(i+id)%5]+=sum[rson][i];
21     }
22 }
23 void build(int l,int r,int u){
24     ll[u]=l;
25     rr[u]=r;
26     memset(sum[u],0,sizeof(sum[u]));
27     if(l==r){
28         num[u]=0;
29         return;
30     }
31     int m=(l+r)/2;
32     build(l,m,lson);
33     build(m+1,r,rson);
34     pushUP(u);
35 }
36 void update(int pos,int u,long long val,int fg){
37     if(ll[u]==rr[u]){
38        sum[u][1]=val*fg;
39        num[u]=1*fg;
40        return;
41     }
42     int m=(ll[u]+rr[u])/2;
43     if(m>=pos)update(pos,lson,val,fg);
44     else
45         update(pos,rson,val,fg);
46     pushUP(u);
47 }
48 
49 int main(){
50    while(~scanf("%d",&n)){
51          top=0;
52        for(int i=1;i<=n;i++){
53           scanf("%s",op[i]);
54           if(op[i][0]=='a'){
55             scanf("%I64d",&a[i]);
56             idx[++top]=a[i];
57           }
58           else if(op[i][0]=='d'){
59             scanf("%I64d",&a[i]);
60           }
61        }
62        sort(idx+1,idx+top+1);
63        int k=unique(idx+1,idx+top+1)-(idx+1);
64          build(1,k,1);
65      for(int i=1;i<=n;i++){
66           if(op[i][0]=='a'){
67            int pos=upper_bound(idx+1,idx+k+1,a[i])-(idx+1);
68             update(pos,1,a[i],1);
69           }
70           else if(op[i][0]=='d'){
71            int pos=upper_bound(idx+1,idx+k+1,a[i])-(idx+1);
72             update(pos,1,0,0);
73           }
74           else{
75             printf("%I64d\n",sum[1][3]);
76           }
77        }
78    }
79 }
View Code

 

posted on 2014-05-21 14:51  天依蓝  阅读(209)  评论(0编辑  收藏  举报

导航