• 题解——洛谷P1383 高级打字机


    原题链接

     原题链接

    算法概述

      读完题目,显然可以用主席树做。

      把所有的插入与撤销操作看成一个序列,按其操作顺序编号,则下标最多为1~n(因为有查询操作的存在,下标实际上不可能到n)。

      在下标上建立主席树。

      每个节点记录其所代表的下标区间内已经插入的字母个数。特别地,叶子节点需要额外记录其下标所对应的操作插入的字母。鉴于本人的字符恐惧症,字母信息直接用数字1~26代替。

      对于插入操作,直接在当前这个操作编号上插入一个字母即可,同时维护区间内字母个数。

      对于撤销操作,假设撤销x步,那就是直接回到x步前的历史版本。

      对于查询操作,假设是查询当前版本的第k个字母,基于线段树的二分结构,对当前所查询到的节点p来说,设其左儿子为L,右儿子为R,节点信息中字母个数为size。若k<=L.size,则递归左儿子,查询第k个字母;否则递归右儿子,查询第k-L.size个字母。

    参考代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=1e5+10;
    
    struct Node{
    	int l,r;
    	int siz;
    	int dat;
    	#define l(p) tree[p].l
    	#define r(p) tree[p].r
    	#define siz(p) tree[p].siz
    	#define dat(p) tree[p].dat
    }tree[N*21];int idx;
    int root[N];
    int n;
    
    int build(int l,int r)
    {
    	int p=++idx;
    	if(l==r)return p;
    	int mid=l+r>>1;
    	l(p)=build(l,mid);
    	r(p)=build(mid+1,r);
    	return p;
    }
    
    int insert(int now,int l,int r,int pos,int ch)
    {
    	int p=++idx;
    	tree[p]=tree[now];
    	if(l==r)
    	{
    		dat(p)=ch;
    		siz(p)=1;
    		return p;
    	}
    	int mid=l+r>>1;
    	if(pos<=mid)l(p)=insert(l(now),l,mid,pos,ch);
    	else r(p)=insert(r(now),mid+1,r,pos,ch);
    	siz(p)=siz(l(p))+siz(r(p));
    	return p; 
    }
    
    int query(int p,int l,int r,int x)
    {
    	if(l==r)return dat(p);
    	int mid=l+r>>1;
    	if(x<=siz(l(p)))return query(l(p),l,mid,x);
    	else return query(r(p),mid+1,r,x-siz(l(p)));
    }
    
    int main()
    {
    	scanf("%d",&n);
    	int cnt=0;
    	for(int i=1;i<=n;i++)
    	{
    		char tp[2];
    		scanf("%s",tp);
    		if(tp[0]=='T')
    		{
    			cnt++;
    			char x;cin>>x;
    			root[cnt]=insert(root[cnt-1],1,n,cnt,x-'a'+1);
    		}
    		else if(tp[0]=='U')
    		{
    			cnt++;
    			int x;scanf("%d",&x);
    			root[cnt]=root[cnt-1-x]; 
    		}
    		else
    		{
    			int x;scanf("%d",&x);
    			char ans=query(root[cnt],1,n,x)-1+'a';
    			printf("%c
    ",ans);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Android studio开发找不到HttpClient问题
    Android studio开发找不到HttpClient问题
    互联网应用之传递HTTP参数
    互联网应用之传递HTTP参数
    计算机组成原理
    计算机组成原理
    【NYOJ】[40]公约数和公倍数
    【NYOJ】[40]公约数和公倍数
    【NYOJ】[39]水仙花数
    【NYOJ】[39]水仙花数
  • 原文地址:https://www.cnblogs.com/ninedream/p/12891511.html
Copyright © 2020-2023  润新知