zoukankan      html  css  js  c++  java
  • P1383 高级打字机 可持久化线段树

      

    题目描述

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

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

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

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

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

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

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

    输入格式

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

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

    输出格式

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

    输入输出样例

    输入 #1
    7
    T a
    T b
    T c
    Q 2
    U 2
    T c
    Q 2
    
    输出 #1
    b
    c


    这题一定要建树(我之前都懒得建树了。。)
    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    
    int T[N<<5],lson[N<<5],rson[N<<5],t[N<<5],ncnt;
    
    void build(int l,int r,int &pos)
    {
        pos=++ncnt;
        if(l==r)return ;
        int m=(l+r)>>1;
        build(l,m,lson[pos]);
        build(m+1,r,rson[pos]);
    }
    
    void up(int x,int v,int l,int r,int pre,int &pos)
    {
        pos=++ncnt;
        lson[pos]=lson[pre];
        rson[pos]=rson[pre];
        if(l==r){t[pos]=v;return ;}
        int m=(l+r)>>1;
        if(x<=m)up(x,v,l,m,lson[pre],lson[pos]);
        else up(x,v,m+1,r,rson[pre],rson[pos]);
    }
    int qsum(int k,int l,int r,int pos)
    {
        if(l==r)return t[pos];
        int m=(l+r)>>1;
        if(k<=m)return qsum(k,l,m,lson[pos]);
        else return qsum(k,m+1,r,rson[pos]);
    }
    char s[2],ss;
    int n,x,rt,len[N];
    
    int main()
    {
        scanf("%d",&n);
        build(1,100005,T[0]);
        int x;
        rep(i,1,n)
        {
            scanf("%s",s);
            if(s[0]=='T')
            {
                cin>>ss;
                rt++;len[rt]=len[rt-1]+1;
                up(len[rt],(int)ss,1,100005,T[rt-1],T[rt]);
            }
            else if(s[0]=='Q')
            {
                cin>>x;
                printf("%c
    ",(char)qsum(x,1,100005,T[rt]));
            }
            else
            {
                cin>>x;rt++;
                T[rt]=T[rt-x-1];
                len[rt]=len[rt-x-1];
            }
        }
        return 0;
    }
    View Code





  • 相关阅读:
    数据库创建索引的缺点,和什么时候不该创建索引
    创建数据库,表,索引,删除索引,查看表中的索引和如何使用表中的索引
    java容器中 哪些是线程安全的
    java中集合类详解
    高并发 问题怎么解决
    数据库20个问题(关于事务、存储引擎、索引、悲观锁乐观锁)
    数据库事务(什么是事务)
    Application对象详解
    get和post 两种基本请求方式的区别
    BZOJ1003物流運輸 DP + SPFA
  • 原文地址:https://www.cnblogs.com/bxd123/p/11296105.html
Copyright © 2011-2022 走看看