Здравствуйте, У меня возникла проблема я когда прочитал и понял как использовать персистентное декартого дерево спотокнулся над одной проблемы. Мы знаем что с помощью персистентной декарткой мы мoжем скопировать отрезок в другой часть массива. Но именно эту операцию я не понял как сделать, и не где не нашел где об этом было рассказано. В простом декартово дерево моя идея заключалась в том что, надо копировать все дерево а потом вырезать отрезак которе мы хотим скопировать у первого дерево, а отрезок где мы хотим вставить наш скопированный отрезок у второго дерево. И потом эти отрезки swap. оставляем второе дерево, а первый больше не нужен. помогите пожалуйста, зарание спасибо!
Вот реализация персистентной дерамиды! Oно работает!
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
struct Node {
long long int val;
int cnt;
long long int sum;
int link;
Node *l; Node *r;
Node() {
link = 0;
val = 0;
cnt = 0;
sum = 0;
l = r = 0;
}
Node(long long int va) {
val = va;
cnt = 1;
sum = va;
link = 0;
l = r = 0;
}
Node(Node *t) {
if (t == 0) {
return;
}
val = t -> val;
cnt = t -> cnt;
sum = t -> sum;
link = 0;
l = t -> l;
r = t -> r;
}
};
int N;
long long int X1, A, B, M;
int K;
void AddLink(Node *t) {
if (t == 0) {
return;
}
t -> link++;
}
void DelNode(Node *t) {
if (t == 0) {
return;
}
t -> link--;
if (t -> link <= 0) {
DelNode(t -> l);
DelNode(t -> r);
delete t;
}
}
int cntt(Node *t) {
if (t == 0) {
return 0;
}
return t -> cnt;
}
long long int ssum(Node *t) {
if (t == 0) {
return 0;
}
return t -> sum;
}
void update(Node *t) {
if (t != 0) {
t -> cnt = cntt(t -> r) + cntt(t -> l) + 1;
t -> sum = ssum(t -> r) + ssum(t -> l) + t -> val;
}
}
Node *merge_t(Node *L, Node *R) {
Node *ptrn = 0;
if (L == 0) {
ptrn = new Node(R);
AddLink(ptrn -> l);
AddLink(ptrn -> r);
return ptrn;
}
if (R == 0) {
ptrn = new Node(L);
AddLink(ptrn -> l);
AddLink(ptrn -> r);
return ptrn;
}
if ((rand() % (L -> cnt + R -> cnt)) > R -> cnt) {
ptrn = new Node(L);
ptrn -> r = merge_t(ptrn -> r, R);
AddLink(ptrn -> l);
AddLink(ptrn -> r);
update(ptrn);
return ptrn;
} else {
ptrn = new Node(R);
ptrn -> l = merge_t(L, ptrn -> l);
AddLink(ptrn -> l);
AddLink(ptrn -> r);
update(ptrn);
return ptrn;
}
}
void split_t(Node *t, int x, Node *&L, Node *&R) {
if (t == 0) {
L = R = 0;
return;
}
Node *cur = new Node(t);
int indexx = cntt(t -> l) + 1;
if (indexx <= x) {
split_t(cur -> r, x - indexx, cur -> r, R);
AddLink(cur -> l);
AddLink(cur -> r);
L = cur;
} else {
split_t(cur -> l, x, L, cur -> l);
AddLink(cur -> l);
AddLink(cur -> r);
R = cur;
}
update(L);
update(R);
}
void printt(Node *t) {
if (t == 0) {
return;
}
printt(t -> l);
printf("%lld ", t -> val);
//cout << t -> val <<" "<< t -> link << endl;
printt(t -> r);
}
int main() {
//freopen("meneger.in", "r", stdin);
//freopen("meneger.out", "w", stdout);
string s;
Node *t = 0;
scanf("%d", &N);
scanf("%lld %lld %lld %lld", &X1, &A, &B, &M);
for (int i = 0; i < N; i++) {
Node *tt;
Node *nt;
if (i == 0) {
tt = new Node(X1);
nt = merge_t(t, tt);
DelNode(t);
DelNode(tt);
t = nt;
} else {
X1 = (A * X1 + B) % M;
tt = new Node(X1);
nt = merge_t(t, tt);
DelNode(t);
DelNode(tt);
t = nt;
}
}
//printt(t);
//cout << endl;
int a, b, w;
scanf("%d", &K);
for (int i = 0; i < K; i++) {
cin >> s;
if (s == "cpy") {
scanf("%d %d %d", &a, &b, &w);
a--; b--;
Node *left = 0;
Node *right = 0;
Node *lleft = 0;
Node *rright = 0;
Node *lr = 0;
Node *sr = 0;
Node *nt;
split_t(t, a, left, right);
DelNode(left);
sr = right;
split_t(right, w, left, right);
DelNode(sr);
DelNode(right);
sr = 0;
split_t(t, b, lleft, rright);
lr = lleft;
sr = rright;
split_t(rright, w, lleft, rright);
DelNode(lleft);
DelNode(sr);
Node *tnt;
nt = merge_t(lr, left);
tnt = nt;
nt = merge_t(nt, rright);
DelNode(lr);
DelNode(left);
DelNode(rright);
DelNode(tnt);
DelNode(t);
t = nt;
} else if (s == "sum") {
scanf("%d %d", &a, &b);
a--;
b -= a;
Node *left;
Node *right;
Node *sr;
split_t(t, a, left, right);
DelNode(left);
sr = right;
split_t(right, b, left, right);
DelNode(sr);
DelNode(right);
printf("%lld\n", left -> sum);
DelNode(left);
} else if (s == "out") {
scanf("%d %d", &a, &b);
a--;
b -= a;
Node *left;
Node *right;
Node *sr;
split_t(t, a, left, right);
DelNode(left);
sr = right;
split_t(right, b, left, right);
DelNode(sr);
DelNode(right);
printt(left);
printf("\n");
DelNode(left);
}
}
return 0;
}








