zoukankan      html  css  js  c++  java
  • [NOI2003]文本编辑器/[AHOI2006]文本编辑器

    XII.初级版:[NOI2003]文本编辑器;进阶版:[AHOI2006]文本编辑器

    两道题操作基本一致,唯一的区别就是进阶版多了一个翻转操作,因此干脆合在一起讲。

    可以使用splay或fhq treap通过。个人认为fhq treap更加直观。

    光标的位置,我们用一个值\(tar\)表示。

    Move/Next/Prev:直接修改\(tar\)的值即可。

    Insert:笛卡尔树\(O(n)\)建树并插入。

    Deletesplit出有效区间然后删掉即可。可以采取空间回收,这是很好的习惯,因为你不知道会不会RE/MLE。

    Get:直接输出split后右半部最靠左那个地方的字符即可。

    Rotate:fhq treap上打区间翻转的tag即可。

    [NOI2003]文本编辑器代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,rt,cnt,bin[5001000],tp,tar,stk[5001000],bd;
    char s[5001000];
    void getstring(int len){
    	char c=getchar();
    	for(int i=0;i<len;i++){
    		while(c>126||c<32)c=getchar();
    		s[i]=c,c=getchar();
    	}
    }
    int read(){
    	int x=0;
    	char c=getchar();
    	while(c>'9'||c<'0')c=getchar();
    	while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
    	return x;
    }
    struct treap{
    	int lson,rson,rd,sz;
    	char ch;
    }t[5001000];
    int newnode(char ch){
    	int x=tp?bin[tp--]:++cnt;
    	t[x].ch=ch,t[x].lson=t[x].rson=0,t[x].sz=1,t[x].rd=rand()*rand();
    	return x;
    }
    void pushup(int x){
    	t[x].sz=1;
    	if(t[x].lson)t[x].sz+=t[t[x].lson].sz;
    	if(t[x].rson)t[x].sz+=t[t[x].rson].sz;
    }
    void split(int x,int k,int &u,int &v){
    	if(!x){u=v=0;return;}
    	if(t[t[x].lson].sz>=k)v=x,split(t[x].lson,k,u,t[x].lson);
    	else u=x,split(t[x].rson,k-t[t[x].lson].sz-1,t[x].rson,v);
    	pushup(x);
    }
    int merge(int x,int y){
    	if(!x||!y)return x+y;
    	if(t[x].rd>t[y].rd){t[x].rson=merge(t[x].rson,y),pushup(x);return x;}
    	else{t[y].lson=merge(x,t[y].lson),pushup(y);return y;}
    }
    void iterate(int x){
    	if(!x)return;
    	iterate(t[x].lson);
    	putchar(t[x].ch);
    	iterate(t[x].rson);
    }
    void oldnode(int x){
    	if(!x)return;
    	oldnode(t[x].lson),oldnode(t[x].rson),bin[++tp]=x;
    }
    int build(int len){
    	int las;
    	for(int i=0;i<len;i++){
    		int x=newnode(s[i]);
    		las=0;
    		while(bd&&t[stk[bd]].rd<t[x].rd)pushup(stk[bd]),las=stk[bd--];
    		if(bd)t[stk[bd]].rson=x;
    		t[stk[++bd]=x].lson=las;
    	}
    	while(bd)pushup(stk[bd--]);
    	return stk[1];
    } 
    void Move(){tar=read();}
    void Insert(){
    	int len=read();
    	getstring(len);
    	int a,b;
    	split(rt,tar,a,b);
    	rt=merge(merge(a,build(len)),b);
    }
    void Delete(){
    	int len=read();
    	int a,b,c;
    	split(rt,tar,a,b);
    	split(b,len,b,c);
    	oldnode(b);
    	rt=merge(a,c);
    }
    void Get(){
    	int len=read();
    	int a,b,c;
    	split(rt,tar,a,b);
    	split(b,len,b,c);
    	iterate(b);putchar('\n'); 
    	rt=merge(merge(a,b),c);
    }
    void Prev(){tar--;}
    void Next(){tar++;}
    int main(){
    	n=read();
    	while(n--){
    		scanf("%s",s);
    		if(s[0]=='I')Insert();
    		else if(s[0]=='M')Move();
    		else if(s[0]=='D')Delete();
    		else if(s[0]=='G')Get();
    		else if(s[0]=='P')Prev();
    		else if(s[0]=='N')Next();
    	}
    	return 0;
    }
    

    [AHOI2006]文本编辑器代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,stk[5001000],tp,bin[5001000],bd,cnt,tar,rt;
    char s[5001000];
    void getstring(int len){
    	for(int i=0;i<len;i++)s[i]=getchar(); 
    }
    int read(){
    	int x=0;
    	char c=getchar();
    	while(c>'9'||c<'0')c=getchar();
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    	return x;
    }
    struct treap{
    	int lson,rson,rd,sz;
    	char ch;
    	bool rev;
    }t[5001000];
    int newnode(char ch){
    	int x=tp?bin[tp--]:++cnt;
    	t[x].lson=t[x].rson=0,t[x].rd=rand()*rand(),t[x].sz=1,t[x].ch=ch,t[x].rev=false;
    	return x;
    }
    void oldnode(int x){
    	if(!x)return;
    	oldnode(t[x].lson),oldnode(t[x].rson),bin[++tp]=x;
    }
    void pushup(int x){
    	t[x].sz=1;
    	if(t[x].lson)t[x].sz+=t[t[x].lson].sz;
    	if(t[x].rson)t[x].sz+=t[t[x].rson].sz;
    }
    void REV(int x){
    	swap(t[x].lson,t[x].rson),t[x].rev^=1;
    }
    void pushdown(int x){
    	if(!t[x].rev)return;
    	REV(t[x].lson),REV(t[x].rson),t[x].rev=false;
    }
    int merge(int x,int y){
    	if(!x||!y)return x+y;
    	if(t[x].rd>t[y].rd){pushdown(x),t[x].rson=merge(t[x].rson,y),pushup(x);return x;}
    	else{pushdown(y),t[y].lson=merge(x,t[y].lson),pushup(y);return y;}
    } 
    void split(int x,int k,int &u,int &v){
    	if(!x){u=v=0;return;}
    	pushdown(x);
    	if(t[t[x].lson].sz>=k)v=x,split(t[x].lson,k,u,t[x].lson);
    	else u=x,split(t[x].rson,k-t[t[x].lson].sz-1,t[x].rson,v);
    	pushup(x);
    }
    void Insert(){
    	int len=read();
    	getstring(len);
    	for(int i=0;i<len;i++){
    		int x=newnode(s[i]),las=0;
    		while(bd&&t[stk[bd]].rd<t[x].rd)pushup(stk[bd]),las=stk[bd--];
    		if(bd)t[stk[bd]].rson=x;
    		t[stk[++bd]=x].lson=las;
    	}
    	while(bd)pushup(stk[bd--]);
    	int a,b;
    	split(rt,tar,a,b);
    	rt=merge(merge(a,stk[1]),b);
    }
    void Delete(){
    	int len=read();
    	int a,b,c;
    	split(rt,tar,a,b);
    	split(b,len,b,c);
    	rt=merge(a,c),oldnode(b);
    }
    void Rotate(){
    	int len=read();
    	int a,b,c;
    	split(rt,tar,a,b);
    	split(b,len,b,c);
    	REV(b),rt=merge(merge(a,b),c);
    }
    void Move(){tar=read();}
    void Next(){tar++;}
    void Prev(){tar--;}
    void leftmost(int x){
    	pushdown(x);
    	if(!t[x].lson){
    		putchar(t[x].ch);
    		if(t[x].ch!='\n')putchar('\n');	
    	}else leftmost(t[x].lson);
    }
    /*
    void iterate(int x){
    	if(!x)return;
    	pushdown(x);
    	iterate(t[x].lson);
    	putchar(t[x].ch);
    	iterate(t[x].rson);
    }
    */
    void Get(){
    	int a,b;
    	split(rt,tar,a,b);
    	leftmost(b);
    	rt=merge(a,b);
    }
    int main(){
    	n=read();
    	while(n--){
    		scanf("%s",s);
    		if(s[0]=='M')Move();
    		else if(s[0]=='I')Insert();
    		else if(s[0]=='D')Delete();
    		else if(s[0]=='R')Rotate();
    		else if(s[0]=='G')Get();
    		else if(s[0]=='P')Prev();
    		else if(s[0]=='N')Next();
    //		iterate(rt),putchar('\n');
    	}
    	return 0;
    }
    

  • 相关阅读:
    .NET:CLR via C# A Brief Look at Metadata
    在容器中运行 Jenkins pipeline 任务
    Azure AI 服务之文本翻译
    linux journalctl 命令
    容器化的 DevOps 工作流
    System V IPC 之消息队列
    System V IPC 之信号量
    System V IPC 之共享内存
    减小容器镜像的三板斧
    linux chroot 命令
  • 原文地址:https://www.cnblogs.com/Troverld/p/14611213.html
Copyright © 2011-2022 走看看