转载请注明出处,谢谢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);} //以上Debug inline 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; }