[BZOJ]1269文本编辑器 做题笔记
2016-02-16 11:22
344 查看
感觉这题出的真心不错,splay可以过,rope可以过,块状链表也可以过
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <map> using namespace std; const int MAX=5000000; int N,val; char ch[20],s[5000000]; struct Splay { int ch[MAX][2],s[MAX],f[MAX],cnt,root,pos; char a[MAX]; bool b[MAX]; void filp (int x) { if (!x) return ; swap(ch[x][0],ch[x][1]); b[x]^=1; } void push (int x) { if (!x) return ; if (b[x]) { filp(ch[x][0]);filp(ch[x][1]); b[x]=0; } } void update (int x) { s[x]=s[ch[x][0]]+s[ch[x][1]]+1; } void rotate (int x) { int y=f[x],opt; if (ch[f[x]][0]==x) opt=0; else opt=1; ch[y][opt]=ch[x][!opt]; if (ch[x][!opt]) f[ch[x][!opt]]=y; f[x]=f[y]; if (root==y) root=x; else if (ch[f[y]][0]==y) ch[f[y]][0]=x; else ch[f[y]][1]=x; f[y]=x,ch[x][!opt]=y; update(y),update(x); } void splay (int x,int to=0) { while (f[x]!=to) { if (f[f[x]]==to) rotate(x); else if ((ch[f[f[x]]][0]==f[x]) ==(ch[f[x]][0]==x)) rotate(f[x]),rotate(x); else rotate(x),rotate(x); } } int build (int L,int R,int fa,char *s) { if (L>R) return 0; int x=++cnt,mid=(L+R)>>1; f[x]=fa; ch[x][0]=build(L,mid-1,x,s); a[x]=s[val++]; ch[x][1]=build(mid+1,R,x,s); update(x); return x; } int find (int k) { int x=root;push(x); while (s[ch[x][0]]+1!=k) { if (k<s[ch[x][0]]+1) x=ch[x][0]; else k-=s[ch[x][0]]+1,x=ch[x][1]; push(x); } return x; } void init () { root=1,cnt=2,pos=1; ch[1][1]=2,f[2]=1,s[1]=2,s[2]=1; } void insert (int len,char *s) { splay(find(pos));splay(find(pos+1),root); val=0; ch[ch[root][1]][0]=build(0,len-1,ch[root][1],s); update(ch[root][1]); update(root); } void del (int n) { splay(find(pos));splay(find(pos+n+1),root); ch[ch[root][1]][0]=0; update(ch[root][1]); update(root); } void op (int n) { splay(find(pos)),splay(find(pos+n+1),root); filp(ch[ch[root][1]][0]); } Splay () { cnt=root=0; } }Sp; int main () { int opt; Sp.init(); scanf("%d",&N); for (int i=1;i<=N;i++) { scanf("%s",ch); if (strcmp(ch,"Move")==0) { scanf("%d",&opt); Sp.pos=opt+1; } else if (strcmp(ch,"Insert")==0) { scanf("%d%*c",&opt); for (int j=0;j<opt;j++) { s[j]=getchar(); } Sp.insert(opt,s); } else if (strcmp(ch,"Delete")==0) { scanf("%d",&opt); Sp.del(opt); } else if (strcmp(ch,"Rotate")==0) { scanf("%d",&opt); Sp.op(opt); } else if (strcmp(ch,"Get")==0) { printf("%c\n",Sp.a[Sp.find(Sp.pos+1)]); } else if (strcmp(ch,"Prev")==0) { Sp.pos--; } else if (strcmp(ch,"Next")==0) { Sp.pos++; } } }
相关文章推荐
- 电阻屏和电容屏的区别
- synchronized的使用方法
- 玩转linux--TFTP
- js获取当前时间戳
- [从头学数学] 第90节 分数乘法
- 深入了解View(一)—— measure测量流程分析
- Java GUI做简易计算器
- 三大框架整合
- java 异常(二)代码
- Spring整合MongoDB
- Fragment生命周期
- 深入理解GCD(一)
- std::set
- iOS开发证书都显示“此证书的签发者无效”,更新WWDR Certificate证书后还是显示无效
- 错误日志分析(dSYM)-2016
- 2016战略规划---小黄人软件
- Jenkins修改workspace和build目录
- javascript函数声明和函数表达式的区别
- 经纬度转凯立德 K 码
- C语言解决百钱买百鸡问题