hdu 4288 Coder(单点操作,查询)
题意:
三种操作:
1. add x – add the element x to the set;
2. del x – remove the element x from the set;
3. sum – find the digest sum of the set.
The digest sum should be understood by:sum(ai) where i % 5 ==3
where the set S is written as {a1, a2, ... , ak} satisfying a1 < a2 < a3 < ... < ak
数据规格:
N ( 1 <= N <= 105 )
1 <= x <= 109.
思路:
BC做过一题和这个一模一样的,,,哎,,,这题早就做过了,可是BC却没有做出来,,,
这个还要离线处理,因为x很大
代码:
int const maxn=1e5+5; struct node{ int cnt; ll sum[5]; }tree[maxn<<2]; int n,tot; int q[maxn],a[maxn]; char ope[maxn][15]; void build(int l,int r,int rt){ tree[rt].cnt=0; memset(tree[rt].sum,0,sizeof(tree[rt].sum)); if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } void pushUp(int rt){ rep(i,0,4) tree[rt].sum[i]=tree[rt<<1].sum[i]+tree[rt<<1|1].sum[((5-tree[rt<<1].cnt%5)%5+i)%5]; } void update(int k,int pos,int num,int l,int r,int rt){ tree[rt].cnt+=k; if(l==r){ tree[rt].sum[0]+=(k*num); return; } int m=(l+r)>>1; if(pos<=m) update(k,pos,num,lson); else update(k,pos,num,rson); pushUp(rt); } int main(){ //freopen("test.in","r", stdin); while(scanf("%d",&n)!=EOF){ tot=0; rep(i,1,n){ scanf("%s",ope[i]); if(ope[i][0]!='s'){ scanf("%d",&q[i]); a[tot++]=q[i]; } } sort(a,a+tot); tot=unique(a,a+tot)-a; //rep(i,0,tot-1) cout<<a[i]<<" "; cout<<endl; if(tot==0) memset(tree[1].sum,0,sizeof(tree[1].sum)); else build(1,tot,1); rep(i,1,n){ int pos=lower_bound(a,a+tot,q[i])-a+1; if(ope[i][0]=='a'){ update(1,pos,q[i],1,tot,1); continue; } if(ope[i][0]=='d'){ update(-1,pos,q[i],1,tot,1); continue; } printf("%I64d\n",tree[1].sum[2]); } } //fclose(stdin); }