P1383 高级打字机

P1383 高级打字机


题目描述

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

Solution

将每个T操作和U操作建一个节点,
对于Q操作, 使用 v e c t o r [ ] vector[] vector[]将该问题编号, 保存在上一个操作节点中
最后离线DFS, 即可 O ( N ) O(N) O(N)处理出每个答案

(这个算法暂且叫它离线树吧…)


Code

#include
#define reg register
#define pb push_back

int read(){
        char c;
        int s = 0, flag = 1;
        while((c=getchar()) && !isdigit(c))
                if(c == '-'){ flag = -1, c = getchar(); break ; }
        while(isdigit(c)) s = s*10 + c-'0', c = getchar();
        return s * flag;
}

const int maxn = 100005;

int N;
int num0, cnt_node, cnt_q;
int head[maxn];
int Ans[maxn];
int que_v[maxn];
char S[maxn];
std::vector <int> que_2[maxn];

struct Edge{
        int nxt, to;
        char w;
        Edge(int nxt=0,int to=0,char w='#'):nxt(nxt), to(to), w(w) {}
} edge[maxn << 1];

void Add(int from, int to, char w){
        edge[num0] = Edge(head[from], to, w);
        head[from] = num0 ++;
}

void DFS(int k, int len){
        int size = que_2[k].size();
        for(reg int i = 0; i < size; i ++) Ans[que_2[k][i]] = S[que_v[que_2[k][i]]];
        for(reg int i = head[k]; ~i; i = edge[i].nxt){
                int to = edge[i].to;
                if(edge[i].w != '#'){
                        S[len + 1] = edge[i].w;
                        DFS(to, len+1);
                }else   DFS(to, len);
        }
}

int main(){
        N = read();
        char opt[3];
        memset(head, -1, sizeof head);
        int last = 0;
        for(reg int i = 1; i <= N; i ++){
                scanf("%s", &opt);
                if(opt[0] == 'T'){
                        scanf("%s", opt);       //reuse opt
                        Add(last, ++ cnt_node, opt[0]);
                }
                else if(opt[0] == 'Q') que_2[last].pb(++ cnt_q), que_v[cnt_q] = read();
                else if(opt[0] == 'U') Add(cnt_node - read() - 1, ++ cnt_node, '#');
                last = cnt_node;
        }
        DFS(0, 0);
        for(reg int i = 1; i <= cnt_q; i ++) printf("%c\n", Ans[i]);
        return 0;
}

你可能感兴趣的:(字符串-离线树,Blue)