您的位置:首页 > 其它

hdu 4288 线段树 (离散化的离线算法)

2012-09-18 15:27 281 查看
输入描述:

输入第一行有一个n 表示接下来有n个命令

接下来的每一行包括一个修改命令 包括一个 字符串命令和一个整数 或者一个求和命令:

  ( 其意思为: add x 将x插入的数组中,del x 从数组中删除,保持数组有序,保证不插入重复的不删除不存在的

    sum 命令表示输出数组中顺序%5==3 的所有元素之和 )

输出描述: 输出每一个sum命令的结果

输入样例:

9

add 1
add 2
add 3
add 4
add 5
sum
add 6
del 3
sum

输出样例:

3

4

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 100005
struct Seg{
int lift,right;
int num;
long long sum[5];//存放每一段区间中顺序%5的各个值之和
void init_seg(int l,int r){
lift=l,right=r,num=0,memset(sum,0,sizeof(sum));
}
} T[MAXN<<2];
char cmd[MAXN];
int x[MAXN];
int ans[MAXN];
void pushup(int i){//向上修改sum值
int t1=(i<<1)+1,t2=t1+1;
for(int j=0; j<5; j++)
T[i].sum[j]=T[t1].sum[j];
for(int j=T[t1].num%5,k=0; k<5; k++,j++)
T[i].sum[j%5]+=T[t2].sum[k];
}
void build(int i,int l,int r){
T[i].init_seg(l,r);
if(l==r)
return;
build((i<<1)+1,l,((l+r)>>1));
build((i+1)<<1,((l+r)>>1)+1,r);
}
int key,add_del;//add_del==1 添加一个数 add_del==-1删除一个数
void update(int i){
if(T[i].lift==T[i].right){
T[i].num^=1;
T[i].sum[0]= add_del==1 ? key : 0;
return;
}
if(ans[(T[i].lift+T[i].right)>>1] >= key)
update((i<<1)+1);
else
update((i+1)<<1);
T[i].num+=add_del;
pushup(i);
}
int main(){
int n,top;
char ch[10];
while(~scanf("%d",&n)){
for(int i=top=0; i<n; i++){
scanf("%s",ch);
cmd[i]=ch[0];
if(ch[0]!='s')
scanf("%d",&x[top]),ans[top]=x[top++];
}
sort(ans,ans+top);
build(0,0,unique(ans,ans+top)-ans-1);
for(int i=0,j=0; i<n; i++){
if(cmd[i]=='s'){
printf("%I64d\n",T[0].sum[2]);
continue;
}
key=x[j++];
add_del= cmd[i]=='a' ? 1 : -1;
update(0);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: