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 }
时间: 2024-12-14 12:24:40

OpenJudge cdqz/Data Structure Challenge 2 (Problem 5822) - 可持久化线段树的相关文章

[BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】

题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于每个点 i 就要连边 (S, i, B[i]) 和 (i, T, W[i]). 这样,如果一个点属于 S 集,就要割掉与 T 相连的边,就相当于失去了染成白色的收益. 我们再来考虑 “奇怪的点”,一个点 i 变成奇怪的点的条件是:i 是黑色且存在一个白色点 j 满足 j < i && L

poj3468A Simple Problem with Integers(线段树的区域更新)

http://poj.org/problem?id=3468 真心觉得这题坑死我了,一直错,怎么改也没戏,最后tjj把q[rt].lz改成了long long 就对了,真心坑啊. 线段树的区域更新. 线段树功能:update:成段增减 query:区间求和 #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; #d

POJ 3468 A Simple Problem with Integers(线段树)

题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 56005   Accepted: 16903 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with

POJ3468 A Simple Problem with Integers 【线段树】+【成段更新】

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 57666   Accepted: 17546 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

PKU A Simple Problem with Integers (线段树区间更新求和)

题意:典型的线段树C,Q问题,有n个数a[i] (1~n),C, a, b,c在[a,b]区间增加c Q a b 求[a,b]的和. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #include<iostream> #include <queue> #i

poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   Accepted: 17753 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 62228   Accepted: 19058 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)

题目链接 题意: 只有这两种操作 C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000."Q a b" means querying the sum of Aa, Aa+1, ... , Ab. 分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久. val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一. 1 #include <iostream

poj3511--A Simple Problem with Integers(线段树求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 60441   Accepted: 18421 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of