splay poj3468

来源:互联网 发布:淘宝买灯具要3c认证吗 编辑:程序博客网 时间:2024/06/04 01:05

早以前就用线段树做过了这个水题。。。

今天为了练习splay,作为splay处理区间的第二题。。。。写了一下午一直tle

准备睡的时候一试结果a了。。。原来是int×int给爆了,转下long long就好了

但是在bsoj上还是过不了啊splay常数那么大就给1s!!!!!

刷不动了。。。就差重写读入了。。。

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define ll long long#define MAX 100000+50using namespace std;int n,m,a[MAX],value[MAX],child[MAX][2],size[MAX];int tot,root,father[MAX];ll add[MAX],he[MAX];void build(int &x,int l,int r){if(l>r){x=0;return;}int mid=(l+r)>>1;x=++tot;size[x]=1;add[x]=0;he[x]=a[mid];value[x]=a[mid];build(child[x][0],l,mid-1);build(child[x][1],mid+1,r);if(child[x][0])father[child[x][0]]=x;if(child[x][1])father[child[x][1]]=x;he[x]=value[x]+he[child[x][0]]+he[child[x][1]];size[x]=size[child[x][0]]+size[child[x][1]]+1;}void down(int x){if(!x)return;value[x]+=add[x];add[child[x][0]]+=add[x];add[child[x][1]]+=add[x];if(child[x][0])he[child[x][0]]+=((long long)add[x]*size[child[x][0]]);if(child[x][1])he[child[x][1]]+=((long long)add[x]*size[child[x][1]]);add[x]=0;}void rotate(int p){int q=father[p],y=father[q],x=(child[q][1]==p);down(q);down(p);father[child[q][x]=child[p][x^1]]=q;father[child[p][x^1]=q]=p;father[p]=y;if(y)child[y][child[y][1]==q]=p;size[q]=size[child[q][0]]+size[child[q][1]]+1;he[q]=he[child[q][0]]+he[child[q][1]]+value[q];//size[p]=size[child[p][0]]+size[child[p][1]]+1;//he[p]=he[child[p][0]]+he[child[p][1]]+value[p];}void splay(int x,int aim=0){down(x);for(int y;(y=father[x])!=aim;rotate(x))if(father[y]!=aim){if((child[y][0]==x)==(child[father[y]][0]==y))rotate(y);elserotate(x);}if(aim==0)root=x;size[x]=size[child[x][0]]+size[child[x][1]]+1;he[x]=he[child[x][0]]+he[child[x][1]]+value[x];}int select(int x){int t=root;while(1){down(t);if(size[child[t][0]]+1==x)break;if(x<=size[child[t][0]])t=child[t][0];else{x-=size[child[t][0]]+1;t=child[t][1];}}return t;}void debug(){printf("i father he value add  size   child_l   child_r\n");for(int i=0;i<=tot;i++)printf("%d %d     %d     %d    %d    %d   %d  %d\n",i,father[i],he[i],value[i],add[i],size[i],child[i][0],child[i][1]);}int main(){scanf("%d%d",&n,&m);for(int i=2;i<=n+1;i++)scanf("%d",&a[i]);root=tot=0;build(root,1,n+2);while(m--){getchar();char ch;scanf("%c",&ch);if(ch=='Q'){int l,r;scanf("%d%d",&l,&r);splay(select(l));splay(select(r+2),root);printf("%lld\n",he[child[child[root][1]][0]]);}else{int l,r,nu;scanf("%d%d%d",&l,&r,&nu);splay(select(l));splay(select(r+2),root);add[child[child[root][1]][0]]+=nu;he[child[child[root][1]][0]]+=((long long)nu*size[child[child[root][1]][0]]);}}return 0;}

0 0