Splay总结
来源:互联网 发布:java所有关键字 编辑:程序博客网 时间:2024/05/16 00:54
写在前面
最近学Splay就好久没有在没有写过博客了,最近想做个总结。
基本思路中所有的树都满足左儿子<树根<右儿子。
题目的所有代码都放在可文章的最后
Bzoj 3224 普通平衡树
http://www.lydsy.com/JudgeOnline/problem.php?id=3224
按值建Splay。
Bzoj 3223 文艺平衡树
http://www.lydsy.com/JudgeOnline/problem.php?id=3223
注意下传标记就可以了。
Bzoj 1588 营业额统计
http://www.lydsy.com/JudgeOnline/problem.php?id=1588
不想写字,会做Bzoj 3224这个题应该没问题。
Bzoj 1269 文本编辑器
http://www.lydsy.com/JudgeOnline/problem.php?id=1269
把光标的前一个字符作为树的根,剩下就简单了。
Bzoj 1507 Editor
http://www.lydsy.com/JudgeOnline/problem.php?id=1507
同Bzoj 1269
Bzoj 1503 郁闷的出纳员
http://www.lydsy.com/JudgeOnline/problem.php?id=1503
扣工资相当于把所有员工工资加上
注意如果某一员工的初始工资小于
Bzoj 1552 robotic sort
http://www.lydsy.com/JudgeOnline/problem.php?id=1552
令物品的编号为
Bzoj 1895 Supermemo
http://www.lydsy.com/JudgeOnline/problem.php?id=1895
revolve x y t,令t = t mod (r-l+1) 。如果t = 0,直接退出。
有两种思路:
一种是一次删除和一次插入。删除[1+y-k,y],再将[1+y-k,y]插入到x前面。
另一种是三次旋转。先后旋转[x,y] , [x,x+k-1] , [x+k,y]。
Bzoj 1500 维修数列
http://www.lydsy.com/JudgeOnline/problem.php?id=1500
注意开内存池就可以了,最大子序和为max{左子树最大子序和,右子树最大子序和,max{左子树右边最大子序和,0}+根节点元素+max{右子树左边最大子序和,0}}。
Bzoj 3224 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 100000+50;const int inf = 0x3f3f3f3f;int ch[Size][2],total[Size],data[Size],pre[Size],size[Size];int tot,root;void Read(int &);void NewNode(int &,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void Insert(int);void Delete(int);int FindRank(int);int Order(int);int GetPre(int);int GetNxt(int);int main(){ int t,x,y; NewNode(root,0,-inf);NewNode(ch[root][1],root,inf); Read(t); while( t-- ){ Read(x);Read(y); if(x==1) Insert(y); else if(x==2) Delete(y); else if(x==3) printf("%d\n",FindRank(y)); else if(x==4) printf("%d\n",Order(y+1)); else if(x==5) printf("%d\n",data[GetPre(y-1)]); else if(x==6) printf("%d\n",data[GetNxt(y+1)]); } return 0;}void Read(int &in){ char ch;int f=1; for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1; for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0'; in *= f;}void NewNode(int &r,int father,int key){ pre[r=++tot] = father; size[r] = total[r] = 1; data[r] = key;}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else { x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Rotate(int r,int way){ int t = pre[r]; pre[ch[t][!way]=ch[r][way]] = t; if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r; pre[r] = pre[t]; pre[ch[r][way]=t] = r; Updata(t);Updata(r);}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+total[r];}void Insert(int x){ Splay(GetPre(x-1),0);Splay(GetNxt(x+1),root); if(ch[ch[root][1]][0]) ++total[ch[ch[root][1]][0]],++size[ch[ch[root][1]][0]]; else NewNode(ch[ch[root][1]][0],ch[root][1],x); Updata(ch[root][1]);Updata(root);}void Delete(int x){ Splay(GetPre(x-1),0);Splay(GetNxt(x+1),root); if(total[ch[ch[root][1]][0]]==1) ch[ch[root][1]][0]=0; else --total[ch[ch[root][1]][0]],--size[ch[ch[root][1]][0]]; Updata(ch[root][1]);Updata(root);}int FindRank(int k){ int ans = 0; int now = root; while(data[now] != k) if(data[now]<k) ans+=(size[ch[now][0]]+total[now]),now=ch[now][1]; else now=ch[now][0]; return ans+size[ch[now][0]];}int Order(int k){ int now = root; while(true) if(size[ch[now][0]]>=k) now=ch[now][0]; else if(size[ch[now][0]]+total[now]>=k) return data[now]; else k-=(size[ch[now][0]]+total[now]),now=ch[now][1];}int GetPre(int x){ int now = root; while(data[now] != x) if(data[now] > x) if(!ch[now][0]) break; else now=ch[now][0]; else if(!ch[now][1]) break; else now=ch[now][1]; while(data[now]>x) now=pre[now]; return now;}int GetNxt(int x){ int now = root; while(data[now] != x) if(data[now] > x) if(!ch[now][0]) break; else now=ch[now][0]; else if(!ch[now][1]) break; else now=ch[now][1]; while(data[now]<x) now=pre[now]; return now;}
Bzoj 3223 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 100000+50;int ch[Size][2],rev[Size],data[Size],pre[Size],size[Size];int root,total;void Read(int &);void NewNode(int &,int,int);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);int Order(int);void PushDown(int);void PushRev(int);void Updata(int);void Rev(int,int);void Display(int);int main(){ int n,m,x,y; Read(n);Read(m); NewNode(root,0,0);NewNode(ch[root][1],root,0); Build(ch[ch[root][1]][0],1,n,ch[root][1]); Updata(ch[root][1]);Updata(root); for(int i=1;i<=m;++i){ Read(x);Read(y); Rev(x,y); } Display(root); return 0;}void Read(int &in){ char ch; for(ch=getchar();ch>'9'||ch<'0';ch=getchar()); for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';}void NewNode(int &r,int father,int key){ pre[r=++total] = father; data[r] = key; size[r] = 1;}void Build(int &node,int l,int r,int father){ if(l > r) return; int mid = (l+r)>>1; NewNode(node,father,mid); Build(ch[node][0],l,mid-1,node); Build(ch[node][1],mid+1,r,node); Updata(node);}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else{ x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root = r;}void Rotate(int r,int way){ int t = pre[r]; pre[ch[t][!way]=ch[r][way]] = t; if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r; pre[r] = pre[t]; pre[ch[r][way]=t] = r; Updata(t);Updata(r);Updata(pre[r]);}int Order(int k){ int now = root; while(true){ PushDown(now); if(size[ch[now][0]]>=k) now = ch[now][0]; else if(size[ch[now][0]]+1==k) return now; else k-=(1+size[ch[now][0]]),now=ch[now][1]; }}void PushDown(int r){ if(!r) return ; if(rev[r]){ PushRev(ch[r][0]); PushRev(ch[r][1]); rev[r] = 0; }}void PushRev(int r){ if(!r) return ; swap(ch[r][0],ch[r][1]); rev[r] ^= 1;}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+1;}void Rev(int l,int r){ Splay(Order(l),0);Splay(Order(r+2),root); PushRev(ch[ch[root][1]][0]);}void Display(int r){ if(!r) return ; PushDown(r); Display(ch[r][0]); if(data[r]) printf("%d ",data[r]); Display(ch[r][1]);}
Bzoj 1588 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = (1<<17)+1;const int inf = 0x3f3f3f3f;int ch[Size][2],data[Size],pre[Size],root,n,total;long long ans;void NewNode(int&,int,int);void Splay(int,int);void Rotate(int,int);int Get(int);int Pre(int);int Nxt(int);void Insert(int);int main(){ scanf("%d%lld",&n,&ans); NewNode(root,0,ans); for(int i=2,r,t;i<=n;++i){ scanf("%d",&r); ans += (t=min(r-Pre(r),Nxt(r)-r)); if(t) Insert(r); } printf("%lld",ans); return 0;}void NewNode(int &r,int father,int key){ pre[r=++total] = father; data[r] = key; ch[r][0] = ch[r][1] = 0;}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else{ x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Rotate(int r,int way){ int tmp=pre[r]; pre[ch[tmp][!way]=ch[r][way]] = tmp; if(pre[tmp]) ch[pre[tmp]][ch[pre[tmp]][1]==tmp] = r; pre[r] = pre[tmp]; pre[ch[r][way]=tmp] = r;}int Get(int x){ int now=root; while(true) if(data[now]==x) break; else if(data[now]>x) if(ch[now][0]) now=ch[now][0]; else break; else if(ch[now][1]) now=ch[now][1]; else break; return now;}int Pre(int x){ int now=Get(x); while(data[now]>x && now) now=pre[now]; if(!now) return -inf; Splay(now,0); return data[root];}int Nxt(int x){ int now=Get(x); while(data[now]<x && now) now=pre[now]; if(!now) return inf; Splay(now,0); return data[root];}void Insert(int x){ int now=root; while(true) if(data[now]>x) if(ch[now][0]) now=ch[now][0]; else break; else if(ch[now][1]) now=ch[now][1]; else break; NewNode(ch[now][data[now]<x],now,x); Splay(ch[now][data[now]<x],0);}
Bzoj 1269 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = (1<<21)+50;int ch[Size][2],pre[Size],size[Size],rev[Size];char data[Size],str[Size],type[20];int root,total;bool first;void NewNode(int &,int,char);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void PushDown(int);void PushRev(int);int Order(int);void Move(int);void Insert(int);void Delete(int);void Rev(int);void Get();void Prev();void Next();void Display(int);void Debug();int main(){ NewNode(root,0,' ');NewNode(ch[root][1],root,' '); Updata(root); int t,n; scanf("%d",&t); while( t-- ){ scanf("%s",type); if(*type=='M') scanf("%d",&n),Move(n); else if(*type=='I') scanf("%d",&n),Insert(n); else if(*type=='D') scanf("%d",&n),Delete(n); else if(*type=='R') scanf("%d",&n),Rev(n); else if(*type=='G') Get(); else if(*type=='P') Prev(); else Next(); } return 0;}void NewNode(int &r,int father,char g){ pre[r=++total] = father; size[r] = 1; data[r] = g;}void Build(int &node,int l,int r,int father){ if(l > r) return ; int mid = (l+r)>>1; NewNode(node,father,str[mid]); Build(ch[node][0],l,mid-1,node); Build(ch[node][1],mid+1,r,node); Updata(node);}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else { x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Rotate(int r,int way){ int t = pre[r]; pre[ch[t][!way]=ch[r][way]] = t; if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r; pre[r] = pre[t]; pre[ch[r][way]=t] = r; Updata(t);Updata(r);}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+1;}void PushDown(int r){ if(rev[r]){ PushRev(ch[r][0]); PushRev(ch[r][1]); rev[r] = 0; }}void PushRev(int r){ if(!r) return ; swap(ch[r][0],ch[r][1]); rev[r] ^= 1;}int Order(int k){ int now = root; while(true){ PushDown(now); if(size[ch[now][0]]>=k) now=ch[now][0]; else if(size[ch[now][0]]+1==k) return now; else k-=(size[ch[now][0]]+1),now=ch[now][1]; }}void Move(int k){ Splay(Order(k+1),0);}void Insert(int k){ for(int i=0;i<k;++i){ str[i] = getchar(); if(str[i]>126 || str[i]<32) --i; } Splay(Order(size[ch[root][0]]+2),root); Build(ch[ch[root][1]][0],0,k-1,ch[root][1]); Updata(ch[root][1]);Updata(root);}void Delete(int k){ Splay(Order(size[ch[root][0]]+2+k),root); ch[ch[root][1]][0] = 0; Updata(ch[root][1]);Updata(root);}void Rev(int k){ Splay(Order(size[ch[root][0]]+2+k),root); PushRev(ch[ch[root][1]][0]);}void Get(){ putchar(data[Order(size[ch[root][0]]+2)]);putchar(10);}void Prev(){ Splay(Order(size[ch[root][0]]),0);}void Next(){ Splay(Order(size[ch[root][0]]+2),0);}void Display(int r){ if(!r) return ; PushDown(r); Display(ch[r][0]); putchar(data[r]); Display(ch[r][1]);}void Debug(){ Display(root);putchar(10);}
Bzoj 1507 代码
#include <cstdio>#include <cstring>#include <algorithm>using std::swap;const int Size = (1<<21)+50;int ch[Size][2],root,total,pre[Size],size[Size];char c[Size],str[Size],type[20];void Init();void NewNode(int&,int,char);void Rotate(int,int);void Splay(int,int);void Build(int&,int,int,int);void Updata(int);int Order(int);void Display(int);void Move(int);void Insert(int);void Delete(int);void Get(int);void Prev();void Next();int main(){ int n,pos; scanf("%d",&n); Init(); while( n-- ){ scanf("%s",type); if(type[0]!='P' && type[0]!='N') scanf("%d",&pos); if(type[0]=='M') Move(pos); else if(type[0]=='I') Insert(pos); else if(type[0]=='D') Delete(pos); else if(type[0]=='G') Get(pos); else if(type[0]=='P') Prev(); else Next(); } return 0;}void Init(){ NewNode(root,0,' '); NewNode(ch[root][1],root,' '); Updata(root);}void NewNode(int &r,int father,char t){ c[r=++total] = t; pre[r] = father; ch[r][0] = ch[r][1] = 0; size[r] = 1;}void Rotate(int r,int way){ int tmp = pre[r]; pre[ch[tmp][!way]=ch[r][way]] = tmp; if(pre[tmp]) ch[pre[tmp]][ch[pre[tmp]][1]==tmp] = r; pre[r] = pre[tmp]; pre[ch[r][way]=tmp] = r; Updata(tmp);Updata(r);Updata(pre[r]);}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]] == goal) Rotate(r,ch[pre[r]][0]==r); else{ x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Build(int &t,int l,int r,int father){ if(l>r) return; int mid = (l+r)>>1; NewNode(t,father,str[mid]); Build(ch[t][0],l,mid-1,t); Build(ch[t][1],mid+1,r,t); Updata(t);}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+1;}int Order(int key){ int now = root; while(true) if(size[ch[now][0]]>=key) now=ch[now][0]; else if(size[ch[now][0]]+1==key) return now; else key-=(1+size[ch[now][0]]),now=ch[now][1];}void Display(int r){ if(!r) return; Display(ch[r][0]); if(r>2) putchar(c[r]); Display(ch[r][1]);}void Move(int k){ Splay(Order(k+1),0);}void Insert(int k){ for(int i=0;i<k;++i){ str[i] = getchar(); if(str[i]<32 || str[i]>126) --i; } Splay(Order(size[ch[root][0]]+2),root); Build(ch[ch[root][1]][0],0,k-1,ch[root][1]); Updata(ch[root][1]),Updata(root);}void Delete(int k){ Splay(Order(size[ch[root][0]]+2+k),root);// printf("<delete>:");Display(ch[ch[root][1]][0]),putchar(10); ch[ch[root][1]][0] = 0; Updata(ch[root][1]),Updata(root);}void Get(int k){ Splay(Order(size[ch[root][0]]+2+k),root); Display(ch[ch[root][1]][0]); putchar(10);}void Prev(){ Splay(Order(size[ch[root][0]]),0);}void Next(){ Splay(Order(size[ch[root][0]]+2),0);}
Bzoj 1503 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 100000+50;const int inf = 0x3f3f3f3f;int ch[Size][2],add[Size],pre[Size],data[Size],total[Size],size[Size];int root,tot,n,mx,ans;void Read(int &);void Read(char &);void NewNode(int &,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void PushDown(int);void PushAdd(int,int);void Insert(int);void Add(int);int Order(int);int GetPre(int);int GetNxt(int);void Display(int);void Debug();int main(){ NewNode(root,0,-inf);NewNode(ch[root][1],root,inf);Updata(root); Read(n);Read(mx); char c; int t; while( n-- ){ Read(c);Read(t); if(c=='I') Insert(t); else if(c=='A') Add(t); else if(c=='S') Add(-t); else printf("%d\n",Order(t+1)); } printf("%d",ans); return 0;}void Read(int &in){ char ch; for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) ; for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';}void Read(char &ch){ for(ch=getchar();ch>'Z'||ch<'A';ch=getchar());}void NewNode(int &r,int father,int key){ pre[r=++tot] = father; data[r] = key; size[r] = total[r] = 1;}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else{ x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Rotate(int r,int way){ int t = pre[r]; pre[ch[t][!way]=ch[r][way]] = t; if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r; pre[r] = pre[t]; pre[ch[r][way]=t] = r; Updata(t);Updata(r);}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+total[r];}void PushDown(int r){ if(!r) return ; if(add[r]){ PushAdd(ch[r][0],add[r]); PushAdd(ch[r][1],add[r]); add[r] = 0; }}void PushAdd(int r,int c){ if(!r) return ; data[r] += c; add[r] += c;}void Add(int c){ Splay(GetPre(-inf),0);Splay(GetNxt(inf),root); PushAdd(ch[ch[root][1]][0],c); if(c < 0){ Splay(GetNxt(mx),root); ans += size[ch[ch[root][1]][0]]; ch[ch[root][1]][0] = 0; Updata(ch[root][1]);Updata(root); }}void Insert(int x){ if(x < mx) {return ;} Splay(GetPre(x-1),0);Splay(GetNxt(x+1),root); if(ch[ch[root][1]][0]) ++size[ch[ch[root][1]][0]],++total[ch[ch[root][1]][0]]; else NewNode(ch[ch[root][1]][0],ch[root][1],x); Updata(ch[root][1]);Updata(root);}int Order(int k){ if(k>=size[root]) return -1; int now = root; while(true){ PushDown(now); if(size[ch[now][1]]>=k) now=ch[now][1]; else if(size[ch[now][1]]+total[now]>=k) return data[now]; else k-=(size[ch[now][1]]+total[now]),now=ch[now][0]; }}int GetPre(int r){ int now = root; while(data[now] != r){ PushDown(now); if(data[now]>r) if(!ch[now][0]) break; else now=ch[now][0]; else if(!ch[now][1]) break; else now=ch[now][1]; } PushDown(now); while(data[now]>r) now=pre[now]; return now;}int GetNxt(int r){ int now = root; while(data[now] != r){ PushDown(now); if(data[now]>r) if(!ch[now][0]) break; else now=ch[now][0]; else if(!ch[now][1]) break; else now=ch[now][1]; } PushDown(now); while(data[now]<r) now=pre[now]; return now;}void Display(int r){ if(!r) return ; PushDown(r); Display(ch[r][0]); printf("%d ",data[r]); Display(ch[r][1]);}void Debug(){ Display(root);putchar(10);}
Bzoj 1552 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int Size = 100000+50;const LL inf = 0x3f3f3f3f3f3f3f3fLL;int ch[Size][2],size[Size],pre[Size],total,root,rev[Size];LL data[Size],mx[Size],a[Size];void Read(int&);void NewNode(int&,int,LL);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void PushRev(int);void PushDown(int);void FindNxt();void Get();void Delete();void Display(int);int main(){ int n; Read(n); for(int i=1,x;i<=n;++i){ Read(x); a[i] = x*100000LL+i; } Build(root,1,n,0); for(int i=1;i<=n;++i){ Get(); if(i != n) printf("%d ",size[ch[root][0]]+i); else printf("%d",size[ch[root][0]]+i); PushRev(ch[root][0]); Delete(); } return 0;}void Read(int &in){ char ch;int f=1; for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1; for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0'; in *= f;}void NewNode(int &r,int father,LL key){ pre[r=++total] = father; ch[r][0] = ch[r][1] = rev[r] = 0; data[r] = key; size[r] = 1;}void Build(int &node,int l,int r,int father){ if(l > r) return ; int mid = (l+r)>>1; NewNode(node,father,a[mid]); Build(ch[node][0],l,mid-1,node); Build(ch[node][1],mid+1,r,node); Updata(node);}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else{ x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Rotate(int r,int way){ int t = pre[r]; pre[ch[t][!way]=ch[r][way]] = t; if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r; pre[r] = pre[t]; pre[ch[r][way]=t] = r; Updata(t);Updata(r);Updata(pre[r]);}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+1; mx[r] = data[r]; if(ch[r][0]) mx[r] = min(mx[r],mx[ch[r][0]]); if(ch[r][1]) mx[r] = min(mx[r],mx[ch[r][1]]);}void PushRev(int r){ if(!r) return ; swap(ch[r][0],ch[r][1]); rev[r] ^= 1;}void PushDown(int r){ if(rev[r]){ PushRev(ch[r][0]); PushRev(ch[r][1]); rev[r] ^= 1; }}void FindNxt(){ if(!ch[root][1]) return ; PushDown(root); int now=ch[root][1]; PushDown(now); while(ch[now][0]){ now=ch[now][0]; PushDown(now); } Splay(now,root);}void Get(){ int now = root; while(data[now] != mx[now]){ PushDown(now); if(mx[ch[now][0]]==mx[now]) now=ch[now][0]; else now=ch[now][1]; } PushDown(now); Splay(now,0);}void Delete(){ if(!ch[root][1]){ root = ch[root][0]; pre[root] = 0; return ; } if(!ch[root][0]){ root = ch[root][1]; pre[root] = 0; return ; } FindNxt(); pre[ch[root][0]] = ch[root][1]; ch[ch[root][1]][0] = ch[root][0]; root = ch[root][1]; pre[root] = 0; Updata(root);}void Display(int now){ if(!now) return ; PushDown(now); Display(ch[now][0]); printf("%lld ",data[now]); Display(ch[now][1]);}
Bzoj 1895 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 200000+20;const int inf = 0x3f3f3f3f;int ch[Size][2],mx[Size],pre[Size],size[Size],rev[Size],add[Size],data[Size],total,root;int a[Size];char str[20];void Read(int &);void NewNode(int&,int,int);void Build(int&,int,int,int);void Splay(int,int);void Rotate(int,int);int Order(int);void PushRev(int);void PushAdd(int,int);void Updata(int);void PushDown(int);void Insert(int,int);void Delete(int);void Reverse(int,int);void Add(int,int,int);void Revolve(int,int,int);int Min(int,int);void Display(int );int main(){ int n,m,pos1,pos2,c; Read(n); for(int i=0;i<n;++i) Read(a[i]); NewNode(root,0,inf);NewNode(ch[root][1],root,inf); Build(ch[ch[root][1]][0],0,n-1,ch[root][1]); Read(m); for(int i=1;i<=m;++i){ scanf("%s",str); if(str[0]=='A') Read(pos1),Read(pos2),Read(c),Add(pos1,pos2,c); else if(str[0]=='I') Read(pos1),Read(c),Insert(pos1,c); else if(str[0]=='D') Read(pos1),Delete(pos1); else if(str[0]=='M') Read(pos1),Read(pos2),printf("%d\n",Min(pos1,pos2)); else if(str[3]=='E') Read(pos1),Read(pos2),Reverse(pos1,pos2); else Read(pos1),Read(pos2),Read(c),Revolve(pos1,pos2,c); } return 0;}void Read(int &in){ int f=1;char ch; for(ch=getchar();ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1; for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0'; in *= f;}void NewNode(int &node,int father,int key){ pre[node=++total] = father; mx[node] = data[node] = key; size[node] = 1;}void Build(int &node,int l,int r,int father){ if(l>r) return ; int mid = (l+r)>>1; NewNode(node,father,a[mid]); Build(ch[node][0],l,mid-1,node); Build(ch[node][1],mid+1,r,node); Updata(node);}void Splay(int node,int goal){ if(node==goal) return ; int x,y,kind; while(pre[node] != goal){ if(pre[pre[node]]==goal){ PushDown(pre[node]);PushDown(node); Rotate(node,ch[pre[node]][0]==node); } else{ x=pre[node];y=pre[x];kind=ch[y][1]==x; PushDown(y);PushDown(x);PushDown(node); if(ch[x][kind]==node) Rotate(x,!kind),Rotate(node,!kind); else Rotate(node,kind),Rotate(node,!kind); } } if(!goal) root=node;}void Rotate(int node,int way){ int tmp=pre[node]; pre[ch[tmp][!way]=ch[node][way]] = tmp; if(pre[tmp]) ch[pre[tmp]][ch[pre[tmp]][1]==tmp] = node; pre[node] = pre[tmp]; pre[ch[node][way]=tmp] = node; Updata(tmp),Updata(node);}int Order(int k){ int now=root; while(true){ PushDown(now); if(size[ch[now][0]]>=k) now=ch[now][0]; else if(size[ch[now][0]]+1==k) return now; else k-=(size[ch[now][0]]+1),now=ch[now][1]; }}void PushRev(int node){ if(!node) return ; swap(ch[node][0],ch[node][1]); rev[node] ^= 1;}void PushAdd(int node,int key){ if(!node) return ; mx[node] += key; data[node] += key; add[node] += key;}void Updata(int node){ if(!node) return ; size[node] = size[ch[node][0]]+size[ch[node][1]]+1; mx[node] = data[node]; if(ch[node][0]) mx[node] = min(mx[ch[node][0]],mx[node]); if(ch[node][1]) mx[node] = min(mx[ch[node][1]],mx[node]);}void PushDown(int node){ if(add[node]){ PushAdd(ch[node][0],add[node]); PushAdd(ch[node][1],add[node]); add[node] = 0; } if(rev[node]){ PushRev(ch[node][0]); PushRev(ch[node][1]); rev[node] = 0; }}void Insert(int pos,int key){ Splay(Order(pos+1),0);Splay(Order(pos+2),root); NewNode(ch[ch[root][1]][0],ch[root][1],key); Updata(ch[root][1]);Updata(root);}void Delete(int pos){ Splay(Order(pos),0);Splay(Order(pos+2),root); ch[ch[root][1]][0] = 0; Updata(ch[root][1]);Updata(root);}void Reverse(int l,int r){ Splay(Order(l),0);Splay(Order(r+2),root); PushRev(ch[ch[root][1]][0]);}void Add(int l,int r,int c){ Splay(Order(l),0);Splay(Order(r+2),root); PushAdd(ch[ch[root][1]][0],c); Updata(ch[root][1]);Updata(root);}void Revolve(int l,int r,int t){ t %= (r-l+1); if(!t) return ; Reverse(l,r); Reverse(l,l+t-1); Reverse(l+t,r);}int Min(int l,int r){ Splay(Order(l),0);Splay(Order(r+2),root); return mx[ch[ch[root][1]][0]];}void Display(int node){ if(!node) return ; PushDown(node); Display(ch[node][0]); printf("%d ",data[node]); Display(ch[node][1]);}
Bzoj 1500 代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 500000+100;const int inf = 0x3f3f3f3f;int ch[Size][2],pre[Size],size[Size],mx[Size],lx[Size],rx[Size];int sum[Size],rev[Size],same[Size],data[Size];int root;int Stack[Size],top;int a[Size];char type[20];void Read(int &);void NewNode(int &,int,int);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);int Order(int);void PushDown(int);void PushSame(int,int);void PushRev(int);void Insert(int,int);void Delete(int,int);void Rec(int);void MakeSame(int,int,int);void Reverse(int,int);int GetSum(int,int);int MaxSum();void Display(int);void Debug();int main(){ for(int i=Size-1;--i;) Stack[++top] = i; NewNode(root,0,-inf);NewNode(ch[root][1],root,-inf);Updata(root); int t,n,pos,tot,c; Read(n);Read(t); for(int i=0;i<n;++i) Read(a[i]); Build(ch[ch[root][1]][0],0,n-1,ch[root][1]); Updata(ch[root][1]);Updata(root); while( t-- ){ scanf("%s",type); if(type[2]!='X') Read(pos),Read(tot); if(type[2]=='S') Insert(pos,tot); else if(type[2]=='L') Delete(pos,tot); else if(type[2]=='K') Read(c),MakeSame(pos,tot,c); else if(type[2]=='V') Reverse(pos,tot); else if(type[2]=='T') printf("%d\n",GetSum(pos,tot)); else printf("%d\n",MaxSum()); } return 0;}void Read(int &in){ char ch;int f=1; for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1; for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0'; in *= f;}void NewNode(int &r,int father,int key){ pre[r=Stack[top--]] = father; sum[r] = data[r] = lx[r] = mx[r] = rx[r] = key; size[r] = 1; ch[r][0] = ch[r][1] = same[r] = rev[r] = 0;}void Build(int &node,int l,int r,int father){ if(l > r) return ; int mid = (l+r)>>1; NewNode(node,father,a[mid]); Build(ch[node][0],l,mid-1,node); Build(ch[node][1],mid+1,r,node); Updata(node);}void Splay(int r,int goal){ int x,y,kind; while(pre[r] != goal) if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else{ x=pre[r];y=pre[x];kind=ch[y][1]==x; if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind); else Rotate(r,kind),Rotate(r,!kind); } if(!goal) root=r;}void Rotate(int r,int way){ int t = pre[r]; pre[ch[t][!way]=ch[r][way]] = t; if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r; pre[r] = pre[t]; pre[ch[r][way]=t] = r; Updata(t);Updata(r);Updata(pre[r]);}void Updata(int r){ if(!r) return ; size[r] = size[ch[r][0]]+size[ch[r][1]]+1; sum[r] = sum[ch[r][0]]+sum[ch[r][1]]+data[r]; lx[r] = sum[ch[r][0]]+data[r]+max(0,lx[ch[r][1]]); if(ch[r][0]) lx[r] = max(lx[r],lx[ch[r][0]]); rx[r] = sum[ch[r][1]]+data[r]+max(0,rx[ch[r][0]]); if(ch[r][1]) rx[r] = max(rx[r],rx[ch[r][1]]); mx[r] = max(0,rx[ch[r][0]])+data[r]+max(0,lx[ch[r][1]]); if(ch[r][0]) mx[r] = max(mx[r],mx[ch[r][0]]); if(ch[r][1]) mx[r] = max(mx[r],mx[ch[r][1]]);}int Order(int k){ int now = root; while(true){ PushDown(now); if(size[ch[now][0]]>=k) now=ch[now][0]; else if(size[ch[now][0]]+1==k) return now; else k-=(size[ch[now][0]]+1),now=ch[now][1]; }}void PushDown(int r){ if(same[r]){ PushSame(ch[r][0],data[r]); PushSame(ch[r][1],data[r]); same[r] = 0; } if(rev[r]){ PushRev(ch[r][0]); PushRev(ch[r][1]); rev[r] = 0; }}void PushSame(int r,int c){ if(!r) return ; data[r] = c; sum[r] = c*size[r]; lx[r] = mx[r] = rx[r] = max(sum[r],c); same[r] = 1;}void PushRev(int r){ if(!r) return ; swap(lx[r],rx[r]); swap(ch[r][0],ch[r][1]); rev[r] ^= 1;}void Insert(int pos,int tot){ for(int i=0;i<tot;++i) Read(a[i]); Splay(Order(pos+1),0); Splay(Order(pos+2),root); Build(ch[ch[root][1]][0],0,tot-1,ch[root][1]); Updata(ch[root][1]);Updata(root);}void Delete(int pos,int tot){ Splay(Order(pos),0); Splay(Order(pos+tot+1),root); Rec(ch[ch[root][1]][0]); ch[ch[root][1]][0] = 0; Updata(ch[root][1]);Updata(root);}void Rec(int r){ if(!r) return ; Stack[++top] = r; Rec(ch[r][0]);Rec(ch[r][1]);}void MakeSame(int pos,int tot,int c){ Splay(Order(pos),0); Splay(Order(pos+tot+1),root); PushSame(ch[ch[root][1]][0],c); Updata(ch[root][1]);Updata(root);}void Reverse(int pos,int tot){ Splay(Order(pos),0); Splay(Order(pos+tot+1),root); PushRev(ch[ch[root][1]][0]); Updata(ch[root][1]);Updata(root);}int GetSum(int pos,int tot){ Splay(Order(pos),0); Splay(Order(pos+tot+1),root); return sum[ch[ch[root][1]][0]];}int MaxSum(){ return mx[root];}void Display(int r){ if(!r) return ; Display(ch[r][0]); printf("%d ",data[r]); Display(ch[r][1]);}void Debug(){ Display(root); putchar(10);}
- Splay总结
- Splay总结
- Splay-总结
- splay总结
- splay总结
- KWY的splay总结
- Splay学习总结
- Splay学习总结
- Splay操作总结
- splay学习总结
- Splay总结、模板
- Splay 总结及模板
- splay的总结
- Splay伸展树模板总结
- SPLAY
- splay
- splay
- splay
- GreenDao的使用
- 区间DP——Dire Wolf ( HDU 5115 )
- NYOJ 1170 最大的数(待续)
- mysql 数据库的事务隔离级别及mysql 索引优化
- matlab:从参考二维矩阵中选择出指定的元素
- Splay总结
- ACM学习历程16——List链表的应用之简单约瑟夫问题
- Thrift应用:Windows下C#服务端实现
- SpringMVC不经过Controller直接响应页面
- Git学习总结
- Java集合类
- 细说JVM系列:JVM内存空间分区
- windows中常用文件位置
- [leetcode]238. Product of Array Except Self -- Java 代码