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

    题目

    发现这样一句话就会导致(T)

    ch[m][0]=++m;
    

    并不是很知道为什么,可能这是某种未定义行为在不同编译器下会有不同后果?

    至于这道题就很简单了,几个有关光标位置的操作就用一个变量模拟就好了

    插入的话把这个位置转出来构造一棵完美(splay)插入就好了

    删除直接转出区间断开的父亲的链接

    输出直接转出区间中序遍历

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 2100005
    #define re register
    char opt[15],S[maxn],val[maxn];
    int n,root,pos,m,len;
    int fa[maxn],ch[maxn][2],sz[maxn];
    inline void update(int x) {sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
    inline void rotate(int x) {
    	int y=fa[x],z=fa[y],k=ch[y][1]==x,w=ch[x][k^1];
    	ch[z][ch[z][1]==y]=x,ch[x][k^1]=y,ch[y][k]=w;
    	update(y),update(x),fa[w]=y,fa[y]=x,fa[x]=z;
    }
    inline void splay(int x,int goal) {
    	while(fa[x]!=goal) {
    		int y=fa[x];
    		if(fa[y]!=goal) rotate((ch[y][1]==x)^(ch[fa[y]][1]==y)?x:y);
    		rotate(x);
    	}
    	if(!goal) root=x;
    }
    inline int kth(int x) {
        int u=root;
        while(1) {
        	if(sz[ch[u][0]]>=x) u=ch[u][0];
        		else if(x>sz[ch[u][0]]+1) x-=sz[ch[u][0]]+1,u=ch[u][1];
        			else return u;
        }
    }
    void dfs(int x) {
    	if(ch[x][0]) dfs(ch[x][0]);
    	putchar(val[x]);
    	if(ch[x][1]) dfs(ch[x][1]);
    }
    int build(int x,int y,int f) {
    	if(x>y) return 0;
    	if(x==y) {
    		val[++m]=S[x];sz[m]=1;fa[m]=f;
    		return m;
    	}
    	int mid=x+y>>1,rt=++m;
    	val[rt]=S[mid];fa[rt]=f;
    	ch[rt][0]=build(x,mid-1,rt),ch[rt][1]=build(mid+1,y,rt);update(rt);
    	return rt;
    }
    int main()
    {
    	scanf("%d",&n);
    	pos=1;
    	root=++m;sz[m]=2;ch[1][0]=++m;
    	sz[m]=1;fa[m]=1;
    	while(n--) {
    		scanf("%s",opt);
    		if(opt[0]=='M') scanf("%d",&pos),pos++;
    		if(opt[0]=='P') pos--;
    		if(opt[0]=='N') pos++;
    		if(opt[0]=='I') {
    			scanf("%d",&len);S[0]=' ';
    			for(re int i=1;i<=len;i++) {
    				S[i]=getchar();
    				if(S[i]=='
    '||S[i]=='
    ') --i;
    			}
    			int aa=kth(pos),bb=kth(pos+1);
    			splay(aa,0),splay(bb,aa);
    			int t=ch[root][1],rt=build(1,len,t);
    			ch[t][0]=rt,update(t),splay(t,0);
    		}
    		if(opt[0]=='D') {
    			scanf("%d",&len);
    			int aa=kth(pos),bb=kth(pos+len+1);
    			splay(aa,0),splay(bb,aa);
    			ch[ch[root][1]][0]=0;update(ch[root][1]);splay(ch[root][1],0);
    		}
    		if(opt[0]=='G') {
    			scanf("%d",&len);
    			int aa=kth(pos),bb=kth(pos+len+1);
    			splay(aa,0),splay(bb,aa);
    			dfs(ch[ch[root][1]][0]);putchar(10);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    MySQL中MyISAM为什么比InnoDB查询快
    .Net Core导入千万级数据至Mysql
    细说MySql索引原理
    原生Swagger界面太low(推荐)
    开源分布式调度系统分享(ScheduleMaster)
    tfs agent cicd 自动编译 xcpoy失败
    .net 网站
    Android App Arch
    Android 多进程引发的一次crash
    Scrapy 抓取数据入门操作
  • 原文地址:https://www.cnblogs.com/asuldb/p/10364636.html
Copyright © 2011-2022 走看看