HDU 4288线段树

来源:互联网 发布:张继科垃圾知乎 编辑:程序博客网 时间:2024/05/16 06:07
//2012成都网赛a题    

思路:  关键是想到直接 将所有出现过的数字作为叶子节点建一棵空的树(就是树中节点暂时不保存任何值)。然后add就添加,del就删,直接模板水之~~~

这道题stl的vector也可以水过 ,真没天理呀。弱菜表示不懂肿么算stl的复杂度了~~~

#include<stdio.h>   #include<string.h>   #include <string>#include <cmath>#include <iostream>#include <map>#include<vector>   #include<queue>#include<algorithm>   #define fr(i,s,n) for(int i=s;i<n;i++)#define pf printf#define sf scanf#define sfv1(a) scanf("%d",&a)#define sfv2(n,m) scanf("%d%d",&n,&m)#define sfv3(u,v,w) scanf("%d%d%d",&u,&v,&w)#define sfstr(c) scanf("%s",c)#define pfv1(a) printf("%d\n",a)#define fi freopen("in.txt","r",stdin)#define fo freopen("out.txt","w",stdout)#define cl(a) memset(a,0,sizeof(a))#define me(a,x) memset(a,x,sizeof(a))#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define Mid (L+R)>>1using namespace std;typedef __int64 ll;const int N=200010;struct Stree{int sum;ll ans[5];}stree[N*4];struct Op{char c[10];int x;}op[N];int num[N];void up(int pos){stree[pos].sum=stree[LL(pos)].sum+stree[RR(pos)].sum;fr(i,0,5){stree[pos].ans[i]=stree[LL(pos)].ans[i]+stree[RR(pos)].ans[(i-stree[LL(pos)].sum%5+5)%5];}}int m;void build(int pos,int L,int R){stree[pos].sum=0;fr(i,0,5){stree[pos].ans[i]=0;}if (L==R){return;}m=Mid;build(LL(pos),L,m);build(RR(pos),m+1,R);}int flag;void update(int pos,int L,int R,int k){if (L==R&&L==k){stree[pos].sum+=flag;stree[pos].ans[0]+=(ll(flag*num[k]));return ;}m=Mid;if (m<k) update(RR(pos),m+1,R,k);else update(LL(pos),L,m,k);up(pos);}int n;int main(){//fi;char c[5];while(sfv1(n)!=EOF){int tot=0,cnt;fr(i,0,n){sfstr(op[i].c);if (op[i].c[0]!='s'){sfv1(op[i].x);num[tot++]=op[i].x;}}if (tot>0){sort(num,num+tot);cnt=unique(num,num+tot)-num;build(1,0,cnt-1);}int pos;fr(i,0,n){if (op[i].c[0]=='s'){pf("%I64d\n",stree[1].ans[2]);}else{pos=lower_bound(num,num+cnt,op[i].x)-num;if (op[i].c[0]=='a') flag=1;else flag=-1;update(1,0,cnt-1,pos);}}}return 0;}

原创粉丝点击