Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <time.h>
- #include <stdlib.h>
- #include <string>
- #include <algorithm>
- using namespace std;
- const long long INF = 1e10;
- struct Treap {
- long long x, y, cnt, minn, add_sum, summ;
- Treap* leftp;
- Treap* rightp;
- };
- long long cnt(Treap* Treap) {
- if (Treap == NULL)
- return 0;
- else
- return Treap->cnt;
- }
- long long minn(Treap* Treap) {
- if (Treap == NULL)
- return INF;
- else
- return Treap->minn;
- }
- long long summ(Treap* Treap) {
- if (Treap == NULL)
- return 0;
- else
- return Treap->summ;
- }
- void push_summ(Treap* Treap){
- if (Treap != NULL)
- {
- Treap->x += Treap->add_sum;
- if (Treap->leftp != NULL)
- Treap->leftp->add_sum += Treap->add_sum;
- if (Treap->rightp != NULL)
- Treap->rightp->add_sum += Treap->add_sum;
- Treap->add_sum = 0;
- }
- }
- void upd_cnt(Treap* Treap)
- {
- if (Treap != NULL) Treap->cnt = 1 + cnt(Treap->rightp) + cnt(Treap->leftp);
- }
- void upd_minn(Treap* Treap)
- {
- if (Treap != NULL) Treap->minn = min(min(minn(Treap->rightp), minn(Treap->leftp)), Treap->x);
- }
- void upd_summ(Treap* Treap)
- {
- if (Treap != NULL) Treap->summ = summ(Treap->rightp) + summ(Treap->leftp) + Treap->x;
- }
- void recalc(Treap* Treap) {
- upd_cnt(Treap);
- upd_minn(Treap);
- push_summ(Treap);
- upd_summ(Treap);
- }
- pair<Treap*, Treap*> split(Treap *root, long long x, long long summ = 0)
- {
- if (root == NULL) {
- return{ NULL, NULL };
- }
- recalc(root);
- int id = summ + cnt(root->leftp);
- if (id < x) {
- auto res = split(root->rightp, x, id + 1);
- root->rightp = res.first;
- recalc(root);
- return{ root, res.second };
- }
- else {
- auto res = split(root->leftp, x, summ);
- root->leftp = res.second;
- recalc(root);
- return{ res.first, root };
- }
- }
- Treap* Merge(Treap* l, Treap* r) {
- recalc(l);
- recalc(r);
- if (l == NULL) {
- return r;
- }
- if (r == NULL) {
- return l;
- }
- if (l->y > r->y) {
- l->rightp = Merge(l->rightp, r);
- recalc(l);
- return l;
- }
- else {
- r->leftp = Merge(l, r->leftp);
- recalc(r);
- return r;
- }
- }
- Treap* Insert(Treap* root, long long value, long long x) {
- auto spl = split(root, x);
- Treap* nw = new Treap({ value, rand(), 1, value, NULL, NULL });
- auto a = Merge(Merge(spl.first, nw), spl.second);
- recalc(a);
- return a;
- }
- Treap* Insert_mass(Treap* root, Treap* nedw, long long x) {
- auto spl = split(root, x);
- auto a = Merge(Merge(spl.first, nedw), spl.second);
- recalc(a);
- return a;
- }
- Treap* del(Treap* root, long long l, long long r) {
- auto spl1 = split(root, l);
- auto spl2 = split(spl1.second, r - l);
- auto a = Merge(spl1.first, spl2.second);
- recalc(a);
- return a;
- }
- Treap* get_sumd(Treap* root, long long l, long long r, long long x) {
- auto spl1 = split(root, l);
- auto spl2 = split(spl1.second, r - l);
- spl2.first->add_sum += x;
- auto a = Merge(spl1.first, Merge(spl2.first, spl2.second));
- recalc(a);
- return a;
- }
- long long get_sum(Treap* root, long long l, long long r) {
- auto spl1 = split(root, l);
- auto spl2 = split(spl1.second, r - l);
- auto ans = summ(spl2.first);
- root = Merge(spl1.first, Merge(spl2.first, spl2.second));
- return ans;
- }
- long long get_min(Treap* root, long long l, long long r) {
- auto spl1 = split(root, l);
- auto spl2 = split(spl1.second, r - l);
- auto ans = minn(spl2.first);
- root = Merge(spl1.first, Merge(spl2.first, spl2.second));
- return ans;
- }
- Treap* revelr(Treap* root, long long l1, long long r1, long long l2, long long r2)
- {
- auto spl1 = split(root, l1);
- auto spl2 = split(spl1.second, r1 - l1);
- auto spl3 = split(spl2.second, l2 - r1);
- auto spl4 = split(spl3.second, r2 - l2);
- auto a1 = Merge(Merge(Merge(Merge(spl1.first, spl4.first), spl3.first), spl2.first), spl4.second);
- recalc(a1);
- return a1;
- }
- void output(Treap* t) {
- if (!t) return;
- push_summ(t);
- output(t->leftp);
- cout << t->x << " ";
- output(t->rightp);
- }
- int main()
- {
- int n, m, rt;
- cin >> n >> m;
- Treap* root = NULL;
- for (int i = 0; i < n; i++)
- {
- cin >> rt;
- root = Insert(root, rt, i);
- }
- int l1, r1, l2, r2;
- for (int i = 0; i < m; i++)
- {
- cin >> rt;
- if (rt == 1)
- {
- cin >> l1 >> r1 >> l2;
- l1--;
- root = get_sumd(root, l1, r1, l2);
- //output(root);
- //cout << endl;
- }
- if (rt == 2)
- {
- cin >> l1 >> r1;
- l1--;
- cout << get_sum(root, l1, r1) << " " << get_min(root, l1, r1) << endl;
- //output(root);
- //cout << endl;
- }
- if (rt == 3)
- {
- cin >> l1 >> r1 >> l2 >> r2;
- l1--; l2--;
- root = revelr(root, min(l1, l2), min(r1, r2), max(l1, l2), max(r1, r2));
- //output(root);
- //cout << endl;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement