Блог пользователя arlanawesome

Автор arlanawesome, история, 11 лет назад, По-русски

Здравствуйте, У меня возникла проблема я когда прочитал и понял как использовать персистентное декартого дерево спотокнулся над одной проблемы. Мы знаем что с помощью персистентной декарткой мы м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;
}

Полный текст и комментарии »

  • Проголосовать: нравится
  • +14
  • Проголосовать: не нравится