SPOJ 4487. Can you answer these queries VI(GSS6 Splay tree)

来源:互联网 发布:中文域名有价值吗 编辑:程序博客网 时间:2024/06/10 17:59

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove

题目:给出4种操作

在某个位置,插入一个数

将某个位置的数删掉

将某个位置的数修改

查询某个区间的最大子段和

http://www.spoj.pl/problems/GSS6/ 

由于有添加和删除,线段树不好处理,其实是可以的,离线读入

Splay对于添加和删除比较方便吧

比较裸的Splay,哭瞎

从WA到TLE,WA的原因是初始化为0了,最大子段和可以是负的

TLE的一点优化貌似是写成结构体,底层优化

#include<iostream>#include<cstring>#include<queue>#include<cstdio>#include<algorithm>#define N 210005#define inf 100000000#define MOD 100000007#define LL long long#define Key_value ch[ch[root][1]][0]#define _match(a,b) ((a)==(b))//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;int n,q,a[N];struct Splay_tree{int size[N],pre[N],val[N],ans[N],lx[N],rx[N],sum[N];int ch[N][2],tot1,root,s[N],tot2;//debug部分copy from hh    void Treaval(int x) {        if(x) {            Treaval(ch[x][0]);            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2c \n",x,ch[x][0],ch[x][1],pre[x],size[x],val[x]);            Treaval(ch[x][1]);        }    }    void debug() {printf("%d\n",root);Treaval(root);}    //以上Debuginline void NewNode(int &r,int k,int father){        if(tot2) r=s[tot2--];else r=++tot1;        ch[r][0]=ch[r][1]=0;pre[r]=father;size[r]=1;val[r]=ans[r]=lx[r]=rx[r]=sum[r]=k;}inline void Push_Up(int x){int l=ch[x][0],r=ch[x][1];size[x]=size[l]+size[r]+1;sum[x]=sum[l]+sum[r]+val[x];lx[x]=max(lx[l],sum[l]+val[x]+max(lx[r],0));rx[x]=max(rx[r],sum[r]+val[x]+max(rx[l],0));ans[x]=max(max(ans[l],ans[r]),val[x]+max(lx[r],0)+max(rx[l],0));}inline void Bulid(int &r,int L,int R,int father){if(L>R)return ;int mid=(L+R)/2;NewNode(r,a[mid],father);Bulid(ch[r][0],L,mid-1,r);Bulid(ch[r][1],mid+1,R,r);Push_Up(r);}inline void Init(){tot1=tot2=root=0;ch[root][0]=ch[root][1]=pre[root]=size[root]=sum[0]=0;lx[root]=rx[root]=val[root]=ans[root]=-inf;NewNode(root,-inf,0);NewNode(ch[root][1],-inf,root);Bulid(Key_value,1,n,ch[root][1]);Push_Up(ch[root][1]);Push_Up(root);}inline void Rotate(int x,int kind){   int y=pre[x];ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;Push_Up(y);}    inline void Splay(int r,int goal){while(pre[r]!=goal){if(pre[pre[r]]==goal)Rotate(r,ch[pre[r]][0]==r);else{int y=pre[r];int kind=(ch[pre[y]][0]==y);if(ch[y][kind]==r){Rotate(r,!kind);Rotate(r,kind);}else{Rotate(y,kind);Rotate(r,kind);}}}Push_Up(r);if(goal==0) root=r;}inline void RotateTo(int k, int goal) {int x=root;while(k!=size[ch[x][0]]+1){if (k<=size[ch[x][0]]){x=ch[x][0];}else{k-=(size[ch[x][0]]+1);x=ch[x][1];}}Splay(x,goal);}inline int Get_Kth(int r,int k){int t=size[ch[r][0]]+1;if(t==k) return r;if(t>k) return Get_Kth(ch[r][0],k);else return Get_Kth(ch[r][1],k-t);}inline void Insert(int pos,int size){RotateTo(pos,0);RotateTo(pos+1,root);NewNode(Key_value,size,ch[root][1]);Push_Up(ch[root][1]);Push_Up(root);}inline void Delete(int pos){RotateTo(pos,0);RotateTo(pos+2,root);Key_value=0;Push_Up(ch[root][1]);Push_Up(root);}inline void Replace(int pos,int m){int x=Get_Kth(root,pos+1);val[x]=m;Splay(x,0);}inline int Query(int x,int y){RotateTo(x,0);RotateTo(y+2,root);return ans[Key_value];}inline void InOrder(int r){if(r==0)return;InOrder(ch[r][0]);printf("%d\n",val[r]);InOrder(ch[r][1]);}inline void Print(){RotateTo(1,0);RotateTo(n+2,root);InOrder(Key_value);}}splay;//外挂忽略char CHAR() {     char res;     while (res = getchar(), !isalpha(res));     return res;}inline void scanf_(int &num){    char in;    bool neg=false;    while(((in=getchar()) > '9' || in<'0') && in!='-') ;    if(in=='-'){        neg=true;        while((in=getchar()) >'9' || in<'0');    }    num=in-'0';    while(in=getchar(),in>='0'&&in<='9')        num*=10,num+=in-'0';    if(neg)        num=0-num;}inline void printf_(int num){    bool flag=false;    if(num<0){        putchar('-');        num=-num;    }    int ans[10],top=0;    while(num!=0){        ans[top++]=num%10;        num/=10;    }    if(top==0)        putchar('0');    for(int i=top-1;i>=0;i--){        char ch=ans[i]+'0';        putchar(ch);    }    putchar('\n');}int main(){    while(scanf("%d",&n)!=EOF){        for(int i=1;i<=n;i++)   scanf_(a[i]);        splay.Init();        scanf_(q);        while(q--){char ch=CHAR();int pos,m;if(ch=='I'){n++;scanf_(pos);scanf_(m);splay.Insert(pos,m);}else if(ch=='D'){n--;scanf_(pos);splay.Delete(pos);}else if(ch=='R'){scanf_(pos);scanf_(m);splay.Replace(pos,m);}else if(ch=='Q'){scanf_(pos);scanf_(m);printf_(splay.Query(pos,m));}}}return 0;}


原创粉丝点击