BZOJ 1269 splay
来源:互联网 发布:网络商业计划书 编辑:程序博客网 时间:2024/05/20 18:40
点击打开链接
题意:中文题目
思路:直接就是splay的几个操作,注意一下光标的位置对于增加和删除的影响就好了
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=2100000;int pre[maxn],ch[maxn][2],size[maxn],root,tot1;//父节点,左右孩子,子树规模,根节点,节点数量int flag[maxn],rev[maxn],m[maxn];//该点的值,懒惰标记int a[maxn],n,q;int s[maxn],tot2,pos;char Istr[maxn],key[maxn];void treaval(int x){//debug部分 if(x){ treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2c add=%2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x],flag[x]); treaval(ch[x][1]); }}void debug(){ printf("root:%d\n",root);treaval(root);}void newnode(int &r,int fa,char k){ if(tot2) r=s[tot2--]; else r=++tot1; pre[r]=fa;size[r]=1;key[r]=m[r]=k;flag[r]=0;rev[r]=0; ch[r][0]=ch[r][1]=0;}void update_rev(int r){ if(r==0) return ; swap(ch[r][0],ch[r][1]); rev[r]^=1;}void update_add(int r,int val){ if(r==0) return ; flag[r]+=val; key[r]+=val; m[r]+=val;}void pushup(int r){ size[r]=size[ch[r][0]]+size[ch[r][1]]+1; m[r]=key[r]; if(ch[r][0]) m[r]=min(m[r],m[ch[r][0]]); if(ch[r][1]) m[r]=min(m[r],m[ch[r][1]]);}void pushdown(int r){ if(rev[r]){ update_rev(ch[r][0]); update_rev(ch[r][1]); rev[r]=0; } if(flag[r]){ update_add(ch[r][0],flag[r]); update_add(ch[r][1],flag[r]); flag[r]=0; }}void buildtree(int &x,int l,int r,int fa){ if(l>r) return ; int mid=(l+r)>>1; newnode(x,fa,Istr[mid]); buildtree(ch[x][0],l,mid-1,x); buildtree(ch[x][1],mid+1,r,x); pushup(x);}void init(){ root=tot1=tot2=0; ch[root][0]=ch[root][1]=pre[root]=size[root]=flag[root]=0; key[root]=0;m[root]=inf; newnode(root,0,inf); newnode(ch[root][1],root,inf);// buildtree(ch[ch[root][1]][0],1,n,ch[root][1]); pushup(ch[root][1]);pushup(root);}void Rotate(int x,int kind){ int y=pre[x]; pushdown(y);pushdown(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; pushup(y);}void splay(int r,int goal){ pushdown(r); while(pre[r]!=goal){ if(pre[pre[r]]==goal){ pushdown(pre[r]);pushdown(r); Rotate(r,ch[pre[r]][0]==r); }else{ pushdown(pre[pre[r]]);pushdown(pre[r]); pushdown(r); 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); } } pushup(r); if(goal==0) root=r;}int get_kth(int r,int k){ pushdown(r); 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);}int get_min(int r){ pushdown(r); while(ch[r][0]){ r=ch[r][0]; pushdown(r); } return r;}int get_max(int r){ pushdown(r); while(ch[r][1]){ r=ch[r][1]; pushdown(r); } return r;}void add(int l,int r,int val){ splay(get_kth(root,l),0); splay(get_kth(root,r+2),root); update_add(ch[ch[root][1]][0],val); pushup(ch[root][1]); pushup(root);}void Reverse(int l,int r){ splay(get_kth(root,l),0); splay(get_kth(root,r+2),root); update_rev(ch[ch[root][1]][0]); pushup(ch[root][1]);pushup(root);}void Insert(int len){ splay(get_kth(root,pos+1),0); splay(get_min(ch[root][1]),root); buildtree(ch[ch[root][1]][0],0,len-1,ch[root][1]); pushup(ch[root][1]);pushup(root);}void erase(int r){ if(r){ s[++tot2]=r; erase(ch[r][0]); erase(ch[r][1]); }}void Delete(int x){ splay(get_kth(root,pos+1),0); splay(get_kth(root,pos+x+2),root); erase(ch[ch[root][1]][0]);pre[ch[ch[root][1]][0]]=0; ch[ch[root][1]][0]=0; pushup(ch[root][1]);pushup(root);}int query_min(int l,int r){ splay(get_kth(root,l),0); splay(get_kth(root,r+2),root); return m[ch[ch[root][1]][0]];}void pri(int x){ if(x==0) return ; pushdown(x); if(ch[x][0]) pri(ch[x][0]); if(key[x]>=0&&key[x]<=1) printf("%d\n",key[x]); if(ch[x][1]) pri(ch[x][1]);}void Revolve(int l,int r){ splay(get_kth(root,l),0); splay(get_kth(root,r+2),root); int tmp=ch[ch[root][1]][0]; ch[ch[root][1]][0]=0; pushup(ch[root][1]);pushup(root); int len=r-l+1; len=n-len+1; splay(get_kth(root,len),0); splay(get_kth(root,len+1),root); ch[ch[root][1]][0]=tmp; pre[ch[ch[root][1]][0]]=ch[root][1]; pushup(ch[root][1]);pushup(root);}int main(){ int x,y,N; char op[20]; while(scanf("%d",&N)!=-1){ init(); while(N--){ scanf("%s",op); if(op[0]=='M'){ scanf("%d",&x);pos=x; }else if(op[0]=='I'){ scanf("%d",&x); getchar(); gets(Istr); Insert(x); }else if(op[0]=='D'){ scanf("%d",&x); Delete(x); }else if(op[0]=='R'){ scanf("%d",&n); Reverse(pos+1,pos+n); }else if(op[0]=='G'){ printf("%c\n",key[get_kth(root,pos+2)]); }else if(op[0]=='P') pos--; else pos++;// cout<<pos<<"==pos"<<endl;// debug(); } } return 0;}/*10Insert 13Balanced eertMove 2Delete 5NextInsert 7 editorMove 0GetMove 11Rotate 4Get*/
0 0
- BZOJ 1269 splay
- BZOJ 1269 文本编辑器 Splay
- bzoj 1269 文本编辑器editor splay
- BZOJ 1588 Splay 入门
- BZOJ 1503 splay
- bzoj 3223(splay)
- bzoj 1552(splay)
- BZOJ 3224 Splay
- bzoj 1588 splay 模板
- BZOJ 1588 splay
- BZOJ 1500 splay
- BZOJ 1588 Splay树
- BZOJ 1507 splay
- BZOJ 5063: 旅游 splay
- BZOJ 1269 [AHOI2006]文本编辑器editor 伸展树splay
- BZOJ 1269 [AHOI2006]文本编辑器editor Splay伸展树
- BZOJ 1269: [AHOI2006]文本编辑器editor 分离合并Splay
- BZOJ 1269 [AHOI 2006] STL(rope)\SPLAY 解题报告
- POJ 2373 Dividing the Path(队列dp)
- Egret开发HTML5小游戏代码分享
- 飞机游戏:屏幕滚动,飞机拖拽,边界设置,子弹跟随
- bzoj 3238 差异
- Source Insight---自定义宏
- BZOJ 1269 splay
- 字符串的分隔方法 split()
- 博客转移到 http://blog.sxin.me
- curse下面的键盘模式输入
- 9.7总结
- 代码的规范性
- Permutations
- 递归解决全排列问题
- 数据重删技术概述