4.13模拟赛

来源:互联网 发布:网络机顶盒电视直播软件下载 编辑:程序博客网 时间:2024/06/06 03:00

Problem 1 高级打字机(type.cpp/c/pas)
【题目描述】
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下3种操作:
1.T x:在文章末尾打下一个小写字母x。(type操作)
2.U x:撤销最后的x次修改操作。(Undo操作)
(注意Query操作并不算修改操作)
3.Q x:询问当前文章中第x个字母并输出。(Query操作)
文章一开始可以视为空串。

【输入格式】
第1行:一个整数n,表示操作数量。
以下n行,每行一个命令。保证输入的命令合法。

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

【样例输入】
7
T a
T b
T c
Q 2
U 2
T c
Q 2
【样例输出】
b
c
【数据范围】
对于40%的数据 n<=200;
对于100%的数据 n<=100000;保证Undo操作不会撤销Undo操作。
高级挑战
对于200%的数据 n<=100000;Undo操作可以撤销Undo操作。
IOI挑战
必须使用在线算法完成该题。
ioi挑战好像就是裸的主席树

#include<bits/stdc++.h>using namespace std;const int maxn = 1000005;int l[3000000],r[3000000],cnt;int root[maxn],len[maxn];char data[3000000];char str[100];void build(int &rt,int _l,int _r){    if(rt==0)rt=++cnt;    if(_l==_r){return;}    int mid=(_l+_r)>>1;    build(l[rt],_l,mid);    build(r[rt],mid+1,_r);}void insert(int pr_rt,int &rt,int _l,int _r,int loc,int val){    if(rt==0)rt=++cnt;    int rtt=rt;    while(_l<=_r){        if(_l==_r){            data[rtt]=val;            break;        }        int mid=(_l+_r)>>1;        if(loc>mid){            l[rtt]=l[pr_rt];            r[rtt]=++cnt;            pr_rt=r[pr_rt];rtt=r[rtt];            _l=mid+1;        }        else{            r[rtt]=r[pr_rt];            l[rtt]=++cnt;            pr_rt=l[pr_rt];rtt=l[rtt];            _r=mid;        }    }}char search(int rt,int _l,int _r,int kth){    while(_l<=_r){        if(_l==_r){            return data[rt];        }        int mid=(_l+_r)>>1;        if(kth > mid){            _l=mid+1;            rt=r[rt];        }        else{            _r=mid;            rt=l[rt];        }    }    return 0;}int main(){    freopen("type.in","r",stdin);    freopen("type.out","w",stdout);    int n=0;    int nw_rt=0,a=0;    int loc=0;    scanf("%d",&n);    build(root[0],1,n);    for(int i=1;i<=n;i++){        scanf("%s",str);        if(str[0] == 'T'){            scanf("%s",str);            nw_rt++;            len[nw_rt]=len[nw_rt-1]+1;            insert(root[nw_rt-1],root[nw_rt],1,n,len[nw_rt],str[0]);        }        else if(str[0] == 'U'){            scanf("%d",&a);            nw_rt++;            root[nw_rt]=root[nw_rt-a-1];            len[nw_rt]=len[nw_rt-a-1];        }        else{            scanf("%d",&a);            printf("%c\n",search(root[nw_rt],1,n,a));        }    }    return 0;}
0 0