gt22 icon

Untitled

gt22 | PRO | 05/02/20 05:52:24 PM UTC | 0 ⭐ | 984 👁️ | Never ⏰ | []
C++ |

5.13 KB

|

None

|

0 👍

/

0 👎

 
 
 
#include "optimization.h"
 
int allocator_pos = 0;
char allocator_memory[1000000000];
#include <tuple>
#include <vector>
#include <random>
 
using namespace std;
 
int U = 4321, L = 54321;
unsigned int cur = 0;
std::mt19937 gen(234);
inline size_t nextRand24() {
//    cur = cur * U + L;
//    return cur >> 8u;
    return gen();
}
 
struct Node;
 
int s(Node *n) noexcept;
 
size_t ss(Node *n) noexcept;
 
struct Node {
    int x;
    Node *l, *r;
    int size = -1;
    int depth = -1;
    size_t sum = -1;
 
 
    Node(size_t x, Node *l = nullptr, Node *r = nullptr) : x(x),
                                                           l(l), r(r) { recalc(); }
 
    Node *withLeft(Node *nl) noexcept {
        return new Node(x, nl, r);
    }
 
    Node *withRight(Node *nr) noexcept {
        return new Node(x, l, nr);
    }
 
    Node *mutateLeft(Node *nl) {
        l = nl;
        recalc();
        return this;
    }
 
    Node *mutateRight(Node *nr) {
        r = nr;
        recalc();
        return this;
    }
 
    void recalc() noexcept {
        size = s(l) + s(r) + 1;
        sum = ss(l) + ss(r) + x;
        depth = max(l ? l->depth : 0, r ? r->depth : 0) + 1;
    }
 
    void full_recalc() noexcept {
        if(l) l->full_recalc();
        if(r) r->full_recalc();
        recalc();
    }
 
    void *operator new(size_t n) {
        char *res = allocator_memory + allocator_pos;
        allocator_pos += n;
        return (void *) res;
    }
 
    void operator delete(void *) noexcept {}
 
};
 
int s(Node *n) noexcept {
    return n ? n->size : 0;
}
 
size_t ss(Node *n) noexcept {
    return n ? n->sum : 0;
}
 
int index(Node *n) noexcept {
    Node *l = n->l;
    return l ? l->size + 1 : 1;
}
 
pair<Node *, Node *> split(Node *t, int i) noexcept {
    if (!t) {
        return {nullptr, nullptr};
    } else if (index(t) < i) {
        auto[a, b] = split(t->r, i - index(t));
        return {t->withRight(a), b};
    } else {
        auto[a, b] = split(t->l, i);
        return {a, t->withLeft(b)};
    }
}
 
tuple<Node *, Node *, Node *> split(Node *t, int l, int r) noexcept {
    auto[a, T] = split(t, l);
    auto[b, c] = split(T, r - s(a));
    return {a, b, c};
}
 
Node *merge(Node *l, Node *r) noexcept {
    if (!l || !r) return l ? l : r;
    else if (nextRand24() % (l->size + r->size) > r->size) {
        return l->mutateRight(merge(l->r, r));
    } else {
        return r->mutateLeft(merge(l, r->l));
    }
}
 
Node *merge(Node *a, Node *b, Node *c) noexcept {
    return merge(merge(a, b), c);
}
 
void traversePrint(Node *t) {
    if(!t) return;
    traversePrint(t->l);
    writeInt(t->x, ' ');
    traversePrint(t->r);
}
 
void print(Node *t, int l, int r) noexcept {
    if (!t || r <= l || r <= 0) return;
    auto[A, B, C] = split(t, l, r);
    traversePrint(B);
}
 
size_t sum(Node *t, int l, int r) noexcept {
    if (!t || r <= l || r <= 0) return 0;
    if (l <= 1 && r > t->size) return t->sum;
    auto[A, B, C] = split(t, l, r);
    return ss(B);
}
 
 
Node *build(const vector<int>& v, int l, int r) {
    if(r <= l) return nullptr;
    if(l == r - 1) return new Node(v[l]);
    int m = (l + r) / 2;
    Node *nn = new Node(v[m]);
    nn->l = build(v, l, m);
    nn->r = build(v, m + 1, r);
    nn->recalc();
    return nn;
}
 
void traverse(Node *t, vector<int>& to) {
    if(!t) return;
    traverse(t->l, to);
    to.push_back(t->x);
    traverse(t->r, to);
}
 
int main() {
    int n = readInt();
    auto X = readInt<size_t>(), A = readInt<size_t>(), B = readInt<size_t>(), M = readInt<size_t>();
    Node *root;
    {
        vector<int> xs;
        xs.reserve(n);
        xs.push_back(X);
        for (int i = 1; i < n; ++i) {
            X = (A * X + B);
            if (X > M) X %= M;
            xs.push_back(X);
        }
        root = build(xs, 0, n);
        assert(root->depth < 30);
    }
    constexpr int Kc = 10000;
    int K = Kc;
    int k = readInt();
    for (int j = 0; j < k; ++j) {
        if(--K == 0) {
            K = Kc;
            vector<int> data;
            data.reserve(n);
            traverse(root, data);
            allocator_pos = 0;
            root = build(data, 0, n);
        }
        int c = readChar();
        readChar();
        readChar();
        switch (c) {
            case 'o': { //out
                auto l = readInt<size_t>(), r = readInt<size_t>();
                print(root, l, r + 1);
                writeChar('\n');
                break;
            }
            case 'c': { //cpy
                auto a = readInt<size_t>(), b = readInt<size_t>(), l = readInt<size_t>();
                auto[A1, B1, C1] = split(root, a, a + l);
                auto[A2, B2, C2] = split(root, b, b + l);
                root = merge(A2, B1, C2);
                break;
            }
            case 's': { //sum
                auto l = readInt<size_t>(), r = readInt<size_t>() + 1;
                writeInt(sum(root, l, r), '\n');
                break;
            }
            default:
                assert(false);
        }
    }
    return 0;
}

Comments