OpenJudge cdqz/Data Structure Challenge 2 (Problem 5822) - 可持久化线段树

描述

给一个空数列,有M次操作,每次操作是以下三种之一:

(1)在数列后加一个数

(2)求数列中某位置的值

(3)撤销掉最后进行的若干次操作(1和3)

输入

第一行一个正整数M。 接下来M行,每行开头是一个字符,若该字符为'A',则表示一个加数操作,接下来一个整数x,表示在数列后加一个整数x;若该字符为'Q',则表示一个询问操作,接下来一个整数x,表示求x位置的值;若该字符为'U',则表示一个撤销操作,接下来一个整数x,表示撤销掉最后进行的若干次操作。

输出

对每一个询问操作单独输出一行,表示答案。

样例输入

9
A 1
A 2
A 3
Q 3
U 1
A 4
Q 3
U 2
Q 3

样例输出

3
4
3

提示

1<=M<=10^5,输入保证合法,且所有整数可用带符号32位整型存储。


  可持久化线段树不解释。

Code

  1 /**
  2  * OpenJudge
  3  * Problem#5822
  4  * Accepted
  5  * Time: 846ms
  6  * Memory: 144000k
  7  */
  8 #include <iostream>
  9 #include <fstream>
 10 #include <sstream>
 11 #include <cstdio>
 12 #include <cstring>
 13 #include <cctype>
 14 #include <cstdlib>
 15 #include <ctime>
 16 #include <algorithm>
 17 #include <map>
 18 #include <set>
 19 #include <stack>
 20 #include <vector>
 21 #include <queue>
 22 using namespace std;
 23 
 24 const int segsize = 300;
 25 
 26 typedef class SegTreeNode {
 27     public:
 28         int val;
 29         SegTreeNode *l, *r;
 30         
 31         SegTreeNode():val(0) {        }
 32 }SegTreeNode;
 33 
 34 SegTreeNode pool[6000000];
 35 SegTreeNode *top = pool;
 36 
 37 SegTreeNode* newnode() {
 38     return top++;
 39 }
 40 
 41 typedef class SegTree {
 42     public:
 43         SegTreeNode** rts;
 44         
 45         SegTree():rts(NULL) {        }
 46         SegTree(int n) {
 47             rts = new SegTreeNode*[(n + 1)];
 48             build(rts[0], 1, n);
 49         }
 50         
 51         void build(SegTreeNode*& node, int l, int r) {
 52             node = newnode();
 53             if(l == r)    return;
 54             int mid = (l + r) >> 1;
 55             build(node->l, l, mid);
 56             build(node->r, mid + 1, r);
 57         }
 58         
 59         void update(SegTreeNode*& newv, SegTreeNode*& oldv, int l, int r, int idx, int val) {
 60             newv = newnode();
 61             *newv = *oldv;
 62             if(l == r) {
 63                 newv->val = val;
 64                 return;
 65             }
 66             int mid = (l + r) >> 1;
 67             if(idx <= mid)    update(newv->l, oldv->l, l, mid, idx, val);
 68             else    update(newv->r, oldv->r, mid + 1, r, idx, val);
 69         }
 70         
 71         int query(SegTreeNode*& node, int l, int r, int idx) {
 72             if(l == r)    return node->val;
 73             int mid = (l + r) >> 1;
 74             if(idx <= mid)    return query(node->l, l, mid, idx);
 75             return query(node->r, mid + 1, r, idx);
 76         }
 77         
 78         SegTreeNode*& operator [] (int pos) {
 79             return rts[pos];
 80         }
 81 }SegTree;
 82 
 83 int n;
 84 int length[100005];
 85 SegTree st;
 86 char s[10];
 87 
 88 inline void solve() {
 89     scanf("%d", &n);
 90     st = SegTree(n);
 91     length[0] = 0;
 92     for(int opt = 1, v = 1, x; opt <= n; opt++) {
 93         scanf("%s%d", s, &x);
 94         switch(s[0]) {
 95             case 'A':
 96                 length[v] = length[v - 1] + 1;
 97                 st.update(st[v], st[v - 1], 1, n, length[v], x), v++;
 98                 break;
 99             case 'Q':
100                 printf("%d\n", st.query(st[v - 1], 1, n, x));
101                 break;
102             case 'U':
103                 length[v] = length[v - x - 1];
104                 st[v] = st[v - x - 1], v++;
105                 break;
106         }
107     }
108 }
109 
110 int main() {
111     solve();
112     return 0;
113 }

 

posted @ 2017-08-06 13:21  阿波罗2003  阅读(316)  评论(0编辑  收藏  举报