BZOJ_1269_文本编辑器_[AHOI2006]_(Spaly)
2016-05-16 22:26
477 查看
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1269
和BZOJ_1507很像的题,多了一个反转操作,还是Splay简单区间操作的模板题.
1269: [AHOI2006]文本编辑器editor
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3223 Solved: 1203
[Submit][Status][Discuss]
Description
这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:
#include <cstdio> #include <algorithm> using namespace std; const int maxn=(1<<21)+5; int n,at,cur,x; char str[maxn],s[10]; struct Splay{ struct node{ node* ch[2],*pa; char v; int s; bool rev; node(char v,node* t):v(v){ ch[0]=ch[1]=pa=t; s=1; rev=false; } bool d() { return pa->ch[1]==this; } void setc(node* t,bool d) { ch[d]=t; t->pa=this; } void push_up() { s=ch[0]->s+ch[1]->s+1; } void push_down(){//向下传递反转 if(rev){ node* c0=ch[0],* c1=ch[1]; setc(c1,0); setc(c0,1);//调换左右子树的位置(貌似可以直接用swap,但刚开始还是自己写吧) ch[0]->rev^=true; ch[1]->rev^=true; rev=false; } } }*root,*null; Splay(){ null=new node('\0',NULL); null->s=0; root=new node('?',null); node* t=new node('!',null); root->setc(t,1); root->push_up(); } void rot(node* o){ node* pa=o->pa; bool d=o->d(); pa->push_down(); o->push_down();//因为会改变o和pa,所以先把标记传递下去. pa->pa->setc(o,pa->d()); pa->setc(o->ch[!d],d); o->setc(pa,!d); pa->push_up(); if(pa==root) root=o; } void splay(node* o,node* pa){ o->push_down();//如果需要转的话,在转的时候会向下传递,但如果不转的话,就在这里向下传递. while(o->pa!=pa){ if(o->pa->pa==pa) rot(o); else o->d()==o->pa->d()?(rot(o->pa),rot(o)):(rot(o),rot(o)); } o->push_up(); } node* kth(int k){ node* t=root; k++; for(t->push_down();;t->push_down()){//每次顺便把标记传递下去. int s=t->ch[0]->s+1; if(s==k) return t; if(k>s) k-=s,t=t->ch[1]; else t=t->ch[0]; } } node* find(int l,int r){ node* L=kth(l); splay(L,null); node* R=kth(r); splay(R,L); return R; } node* build(int l,int r){ if(l==r) return new node(str[l],null); if(l>r) return null; int m=l+(r-l)/2; node* t=new node(str[m],null); t->setc(build(l,m-1),0); t->setc(build(m+1,r),1); t->push_up(); return t; } void insert(int at,int cur){ node* t=find(at,at+1); t->setc(build(0,cur),0); t->push_up();//因为在find函数中t是被splay过的,在splay中已经向下传递过标记了,所以这里不必再传递(remove函数中相同). splay(t,null); } void remove(int at,int n){ node* t=find(at,at+n+1); t->setc(null,0); t->push_up(); splay(t,null); } void setrev(int at,int n){//反转函数 node* t=find(at,at+n+1); t->ch[0]->rev^=true; t->push_down(); } void print(node* o){ if(o==null) return; o->push_down();//先向下传递,不然会错. print(o->ch[0]); printf("%c",o->v); print(o->ch[1]); } void print(int at,int n){ node* t=find(at,at+n+1); print(t->ch[0]); printf("\n"); } }tree; int main(){ scanf("%d",&n); while(n--){ scanf("%s",s); if(s[0]=='I'){ scanf("%d",&x); cur=0; while(x--){ while(str[cur]=getchar(),str[cur]=='\n'); cur++; } cur--; tree.insert(at,cur); } else if(s[0]=='M') scanf("%d",&at); else if(s[0]=='D'){ scanf("%d",&x); tree.remove(at,x); } else if(s[0]=='G') tree.print(at,1); else if(s[0]=='R'){ scanf("%d",&x); tree.setrev(at,x); } else if(s[0]=='P') at--; else at++; } return 0; }View Code
相关文章推荐
- javascript:js脚本的3中引入方法
- No TypeTag available for person
- Centos 7 安装VNC步骤
- leetcode.10. Regular Expression Matching
- [动态规划]之裸lis之最长上升子序列POJ 2533
- Java中补码的规则
- osg布告板技术(Billboard)
- getRequestDispatcher ,sendRedirect
- 测试并发编程demo
- 求成绩
- hdoj 5681 zxa and wifi
- MySQL:Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEM
- shell脚本的使用---if变量编写lamp管理脚本
- hdu_4824_Disk Schedule(dp)
- QT信号槽多次连接引起的错误修改
- mybatis查询没有返回结果,程序不继续执行
- javascript基础-黑白反斗棋
- 使用Jmeter进行http接口测试
- centos 的权限管理--自主访问控制DAC和访问控制列表 ACL
- hdu_4824_Disk Schedule(dp)