zoukankan      html  css  js  c++  java
  • Bzoj 3333 高级打字机(主席树)

    3333 高级打字机
    时间限制: 1 s
    空间限制: 256000 KB
    题目等级 : 大师 Master
    题目描述 Description
    早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
    请为这种高级打字机设计一个程序,支持如下3种操作:
    1.T x:在文章末尾打下一个小写字母x。(type操作)
    2.U x:撤销最后的x次修改操作。(Undo操作)
    (注意Query操作并不算修改操作)
    3.Q x:询问当前文章中第x个字母并输出。(Query操作)
    文章一开始可以视为空串。
    输入描述 Input Description
    第1行:一个整数n,表示操作数量。
    以下n行,每行一个命令。保证输入的命令合法。
    输出描述 Output Description
    每行输出一个字母,表示Query操作的答案。
    样例输入 Sample Input
    7
    T a
    T b
    T c
    Q 2
    U 2
    T c
    Q 2
    样例输出 Sample Output
    b
    c
    数据范围及提示 Data Size & Hint
    对于40%的数据 n<=200;
    对于50%的数据 n<=100000;保证Undo操作不会撤销Undo操作。
    <高级挑战>
    对于100%的数据 n<=100000;Undo操作可以撤销Undo操作。

    /*
    主席树.
    一开始傻逼了.
    想要维护这个时间点的一个状态.
    然后发现这样维护状态是不合法的.
    比如说删除操作后无法和上一个时间点建立联系.
    更别说维护链了.
    大概没有人和我这么傻逼吧orz.
    题目编号亮了hhh.
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 100001
    using namespace std;
    int n,n1,root[MAXN],t,tot,size[MAXN];
    struct data{int lc,rc,x;}tree[MAXN*20];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int &k,int last,int l,int r,int x,int y)
    {
        k=++tot;tree[k].lc=tree[last].lc,tree[k].rc=tree[last].rc;
        if(l==r) {tree[k].x=y;return ;}
        int mid=(l+r)>>1;
        if(x<=mid) add(tree[k].lc,tree[last].lc,l,mid,x,y);
        else add(tree[k].rc,tree[last].rc,mid+1,r,x,y);
        return ;
    }
    void query(int k,int l,int r,int x)
    {
        if(l==r) 
        {
            printf("%c
    ",tree[k].x+96);
            return ;
        }
        int mid=(l+r)>>1;
        if(x<=mid) return query(tree[k].lc,l,mid,x);
        else return query(tree[k].rc,mid+1,r,x);
    }
    int main()
    {
        int x;char y;
        n=read();char ch[3];
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch);
            if(ch[0]=='T') 
            {
                cin>>y;t++;
                size[t]=size[t-1]+1;
                add(root[t],root[t-1],1,n,size[t],int(y-96));
            }
            else if(ch[0]=='U')
            {
                x=read();
                root[t+1]=root[t-x];
                size[t+1]=size[t-x];
                t++;
            }
            else {
                x=read();//root[i]=root[i-1];
                //size[i]=size[i-1];
                query(root[t],1,n,x);
                n1++;
            }
        }
        return 0;
    }
  • 相关阅读:
    BZOJ3252攻略——长链剖分+贪心
    BZOJ3522[Poi2014]Hotel——树形DP
    BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
    BZOJ3626[LNOI2014]LCA——树链剖分+线段树
    BZOJ2157旅游——树链剖分+线段树
    BZOJ3531[Sdoi2014]旅行——树链剖分+线段树
    BZOJ2243[SDOI2011]染色——树链剖分+线段树
    zookeeper(1)初识zookeeper
    任督二脉
    RPC框架之RMI
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068065.html
Copyright © 2011-2022 走看看