您的位置:首页 > 其它

hdu 4288 五颗线段树

2012-09-17 17:37 183 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4288

/*
题目:给出一个有序集合,3种操作。插入一个数,删除一个数,都保证序列有序。以及求和
其中求和是将下标%5==3的所有数求和
解法:
五颗线段树!!
前段时间刚做了,十颗线段树!!现在再做五颗的就哑火了!!!比赛时,不敢做!!后面的更简单题目没有出来,
这个题目就不敢做了!!我表示弱校伤不起,弱菜伤不起!!
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<memory.h>
using namespace std;
const int maxn=100002;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
__int64 sum[maxn<<2][6];
char op[maxn][20];
int num[maxn<<2],n,a[maxn],idx[maxn];//表示左移距离
void pushUp(int rt)
{
num[rt]=num[rt<<1]+num[rt<<1|1];
int id=num[rt<<1];
for(int i=0; i<5; i++)
{
sum[rt][i]=sum[rt<<1][i];
}
for(int i=0; i<5; i++)
{
sum[rt][(i+id)%5]+=sum[rt<<1|1][i];
}
}
void build(int rt,int l,int r)
{

num[rt]=0;
for(int i=0; i<5; i++) sum[rt][i]=0;
if(l==r) return;
int mid=(l+r)>>1;
build(lson);
build(rson);
}
void updata(int rt,int l,int r,int pos,int op)//op=1 表示 add; op=0 表示 del;
{
if(l==r)
{
num[rt]=op;
sum[rt][1]=op*idx[l];
return ;
}
int mid=(l+r)>>1;
if(pos<=mid)
updata(lson,pos,op);
else
updata(rson,pos,op);
pushUp(rt);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i,j,k=0;
for(i=0; i<n; i++)
{
scanf("%s",&op[i]);
if(op[i][0]!='s')
{
scanf("%d",&a[i]);
if(op[i][0]=='a')
{
idx[++k]=a[i];
}
}
}
sort(idx+1,idx+k+1);//因为没有排序WA了无数次!!
k=unique(idx+1,idx+k+1)-(idx+1);
build(1,1,k);
for(i=0; i<n; i++)
{
int pos=upper_bound(idx+1,idx+k+1,a[i])-(idx+1);
if(op[i][0]=='a')
{
updata(1,1,k,pos,1);
}
else if(op[i][0]=='d')
{
updata(1,1,k,pos,0);
}
else printf("%I64d\n",sum[1][3]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: