可持久化树模板
您需要维护一个序列,其中需要提供以下操作:
-
插入一个数到序列的第 t 版本使其成为序列的第 k 项,这个数为 x ;
-
删除序列的第 t 版本的第 k 项;
-
查询序列的第 t 版本的第 k 项。
第 0 个版本为空序列。修改操作不会影响被修改的版本,而总是产生一个新版本。
Input
第一行有一个正整数 n 表示操作的数量。
接下来 n 行每行第一个正整数 opt 表示操作的类型,后面有 3 个整数 t,k,x 或 2 个整数 t,k 表示操作的参数。
1 ≤ n ≤ 3×105 , 1 ≤ opt ≤ 3 , 0 ≤ x < 109 ,保证所有操作合法。
由于数据量较大,可能需要使用特别的读入方式。
Output
对于每个查询操作输出一行一个数,表示查询的结果。
Sample Input
17
1 0 1 1
1 1 1 2
1 2 1 3
2 3 2
3 4 2
1 4 3 4
1 5 1 5
3 3 2
1 3 4 6
1 6 3 7
1 7 1 8
3 8 2
3 7 3
2 8 4
2 9 2
3 11 4
3 10 4
Sample Output
1
2
3
1
6
4
Hint
每次操作后的序列如下
1 | 1
2 | 2 1
3 | 3 2 1
4 | 3 1
(=> 1)
5 | 3 1 4
6 | 5 3 1 4
(=> 2)
7 | 3 2 1 6
8 | 5 3 7 1 4
9 | 8 3 2 1 6
(=> 3)
(=> 1)
10 | 5 3 7 4
11 | 8 2 1 6
(=> 6)
(=> 4)
//Splay Tree #include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define scl(i) scanf("%lld", &i) #define scll(i, j) scanf("%lld %lld", &i, &j) #define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k) #define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l) #define scs(i) scanf("%s", i) #define sci(i) scanf("%d", &i) #define scd(i) scanf("%lf", &i) #define scIl(i) scanf("%I64d", &i) #define scii(i, j) scanf("%d %d", &i, &j) #define scdd(i, j) scanf("%lf %lf", &i, &j) #define scIll(i, j) scanf("%I64d %I64d", &i, &j) #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k) #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k) #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k) #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l) #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l) #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l) #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define lowbit(i) (i & (-i)) #define mem(i, j) memset(i, j, sizeof(i)) #define fir first #define sec second #define VI vector<int> #define ins(i) insert(i) #define pb(i) push_back(i) #define pii pair<int, int> #define VL vector<long long> #define mk(i, j) make_pair(i, j) #define all(i) i.begin(), i.end() #define pll pair<long long, long long> #define _TIME 0 #define _INPUT 0 #define _OUTPUT 0 clock_t START, END; void __stTIME(); void __enTIME(); void __IOPUT(); using namespace std; /* rope rope(rope&); //构造函数、传入rope可以用来拷贝 push_back(x); // 在末尾添加x insert(pos, x); // 在pos插入x erase(pos, x); // 从pos开始删除x个 copy(pos, len, x); // 从pos开始到pos+len为止用x代替 replace(pos, x); // 从pos开始换成x substr(pos, x); // 提取pos开始x个 at(x) / [x]; // 访问第x个元素 时间复杂度为n*(n^0.5) */ #include <ext/rope> using namespace __gnu_cxx; const int maxn = 3e5 + 10; int n, id; rope<int> * Rope[maxn]; int main(void){__stTIME();__IOPUT(); int n; sci(n); Rope[0] = new rope<int>(); while(n--){ int op, t, k, x; sciii(op, t, k); if(op == 1){ sci(x); Rope[++id] = new rope<int>(*Rope[t]); Rope[id]->insert(k - 1, x); } if(op == 2){ Rope[++id] = new rope<int>(*Rope[t]); Rope[id]->erase(k - 1, 1); } if(op == 3) printf("%d\n", Rope[t]->at(k-1)); } __enTIME();return 0;} void __stTIME() { #if _TIME START = clock(); #endif } void __enTIME() { #if _TIME END = clock(); cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl; #endif } void __IOPUT() { #if _INPUT freopen("in.txt", "r", stdin); #endif #if _OUTPUT freopen("out.txt", "w", stdout); #endif }