码迷,mamicode.com
首页 > 其他好文 > 详细

P1383 高级打字机

时间:2019-11-11 09:36:16      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:val   class   vector   mes   build   nlog   修改   字母   undo   

P1383 高级打字机

Description

  • 早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。

    请为这种高级打字机设计一个程序,支持如下3种操作:

    1.T x:在文章末尾打下一个小写字母x。(type操作)

    2.U x:撤销最后的x次修改操作。(Undo操作)

    (注意Query操作并不算修改操作)

    3.Q x:询问当前文章中第x个字母并输出。(Query操作)

    文章一开始可以视为空串。

Input

  • 第1行:一个整数n,表示操作数量。

    以下n行,每行一个命令。保证输入的命令合法。

Output

  • 每行输出一个字母,表示Query操作的答案。

Sample Input

7
T a
T b
T c
Q 2
U 2
T c
Q 2

Sample Output

b
c

Data Size

  • 【数据范围】

    对于40%的数据 n<=200;

    对于100%的数据 n<=100000;保证Undo操作不会撤销Undo操作。

    <高级挑战>

    对于200%的数据 n<=100000;Undo操作可以撤销Undo操作。

    必须使用在线算法完成该题。

题解:

  • 主席树。
  • 一开始无脑水了个vector上去,80pts。爆空间了。如果全是插入操作的话,空间复杂度近似于O(n^2)。后来就敲了一发主席树就过了。原因是每次插入操作都只是开了一条链的空间而已。总体空间复杂度大概是O(nlogn)(大概
  • 具体思路比较简单,每一个时间戳建一棵树,拿个数组记录每棵树插入到第几个位置然后就在原树上插入;撤销直接rt[i]=rt[i-x];查询查就是了。
#include <iostream>
#include <cstdio>
#define N 100005
using namespace std;

struct T {int l,r,v;}t[N*32];
int n,dfn,dex;
int cnt[N],rt[N];

int build(int l,int r)
{
    int p=++dex,mid=l+r>>1;
    if(l==r) return p;
    t[p].l=build(l,mid);
    t[p].r=build(mid+1,r);
    return p;
}

int upd(int lat,int l,int r,int pos,int val)
{
    int p=++dex,mid=l+r>>1;
    t[p]=t[lat];
    if(l==r) {t[p].v=val;return p;}
    if(pos<=mid) t[p].l=upd(t[lat].l,l,mid,pos,val);
    else t[p].r=upd(t[lat].r,mid+1,r,pos,val);
    return p;
}

int ask(int p,int l,int r,int pos)
{
    if(l==r) return t[p].v;
    int mid=l+r>>1;
    if(pos<=mid) return ask(t[p].l,l,mid,pos);
    return ask(t[p].r,mid+1,r,pos);
}

int main()
{
    cin>>n;
    rt[0]=build(1,n);
    for(int i=1;i<=n;i++)
    {
        char c[3]; scanf("%s",c);
        if(c[0]=='T') {
            char x[3]; scanf("%s",x);
            dfn++,rt[dfn]=upd(rt[dfn-1],1,n,cnt[dfn-1]+1,x[0]-'a'+1);
            cnt[dfn]=cnt[dfn-1]+1;
        }
        else if(c[0]=='U') {
            int x; scanf("%d",&x);
            dfn++,rt[dfn]=rt[dfn-x-1];
            cnt[dfn]=cnt[dfn-x-1];
        }
        else if(c[0]=='Q') {
            int x; scanf("%d",&x);
            printf("%c\n",ask(rt[dfn],1,n,x)-1+'a');
        }
    }
    return 0;
}

P1383 高级打字机

标签:val   class   vector   mes   build   nlog   修改   字母   undo   

原文地址:https://www.cnblogs.com/BigYellowDog/p/11832721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!