您的位置:首页 > 其它

hdu 4288 Coder

2014-08-15 08:37 309 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4288

题意:add 就是在集合里面加上一个数x; del 就是从集合里删去一个数x; sum是求位置i%5==3的数的和。

tree[i].sum[5] 里面数组存的是不同位置%5之后分别对应的和。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
using namespace std;

char str[maxn][4];
int x[maxn],xx[maxn];
struct node
{
int r,l;
__int64 sum[6];
int cnt;
}tree[maxn*4];

void build(int i,int l,int r)
{
tree[i].l=l;tree[i].r=r;
for(int j=0; j<5; j++) tree[i].sum[j]=0;
tree[i].cnt=0;
if(l==r) return ;
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
}

void update(int i,int l,int r,int c,int num)
{
tree[i].cnt+=num;
if(tree[i].l==l&&tree[i].r==r)
{
tree[i].sum[0]+=c;
return ;
}
int mid=(tree[i].l+tree[i].r)>>1;
if(r<=mid)
{
update(i<<1,l,r,c,num);
}
else if(l>mid)
{
update(i<<1|1,l,r,c,num);
}
else
{
update(i<<1,l,mid,c,num);
update(i<<1|1,mid+1,r,c,num);
}
for(int j=0; j<5; j++)
{
tree[i].sum[j]=tree[i<<1].sum[j]+tree[i<<1|1].sum[((j-tree[i<<1].cnt)%5+5)%5];
}
}
int bs(int l,int r,int data)
{
while(l<=r)
{
int mid=(l+r)>>1;
if(xx[mid]==data)
{
return mid;
}
else if(xx[mid]>data)
{
r=mid-1;
}
else
l=mid+1;
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int t1=0;
for(int i=0; i<n; i++)
{
scanf("%s",str[i]);
if(strcmp(str[i],"sum"))
{
scanf("%d",&x[i]);
xx[t1++]=x[i];
}
}
sort(xx,xx+t1);
t1=unique(xx,xx+t1)-xx;
build(1,1,t1);
for(int i=0; i<n; i++)
{
int l1=bs(0,t1-1,x[i]);
if(!strcmp(str[i],"add"))
{
update(1,l1+1,l1+1,x[i],1);
}
else if(!strcmp(str[i],"del"))
{
update(1,l1+1,l1+1,-x[i],-1);
}
else if(!strcmp(str[i],"sum"))
{
printf("%I64d\n",tree[1].sum[2]);
}
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: