Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- #include <set>
- #include <map>
- #include <stack>
- #include <queue>
- #include <cstdlib>
- #include <cstdio>
- #include <string>
- #include <utility>
- #include <iomanip>
- using namespace std;
- struct node {
- int val, cnt, y;
- long long sum;
- bool rev;
- node *l,*r;
- node () {}
- node (int val, int y) : y(y), val(val), cnt(1), sum(val), rev(false), l(NULL), r(NULL) {}
- };
- typedef node * pnode;
- int cnt(pnode t) {
- if (t == NULL)
- return 0;
- else
- return t->cnt;
- }
- long long sum(pnode t) {
- if (t == NULL)
- return 0;
- else
- return t->sum;
- }
- void upd(pnode t) {
- if (t != NULL) {
- t->cnt = cnt(t->l) + 1 + cnt(t->r);
- t->sum = sum(t->l) + t->val + sum(t->r);
- }
- }
- void push(pnode t) {
- if (t && t->rev) {
- swap(t->l, t->r);
- if (t->l)
- t->l->rev ^= true;
- if (t->r)
- t->r->rev ^= true;
- t->rev = false;
- }
- }
- void merge(pnode &t, pnode l, pnode r) {
- push(l); push(r);
- if (l == NULL)
- t = r;
- else if (r == NULL)
- t = l;
- else if (l->y > r->y) {
- merge(l->r, l->r, r); t = l;
- }
- else {
- merge(r->l, l, r->l); t = r;
- }
- upd(t);
- }
- void split(pnode t, pnode &l, pnode &r, int x, int add = 0) {
- push(t);
- if (t == NULL) {
- l = r = NULL;
- return;
- }
- int key = cnt(t->l) + 1 + add;
- if (x <= key) {
- split(t->l, l, t->l, x, add); r = t;
- }
- else {
- split(t->r, t->r, r, x, add + cnt(t->l) + 1); l = t;
- }
- upd(t);
- }
- void reverse(pnode t, int l, int r) {
- pnode a,b;
- split(t,t,a,l,0);
- split(a,a,b,r-l+2,0);
- a->rev^=true;
- merge(t,t,a);
- merge(t,t,b);
- }
- void swapper(pnode &odd, pnode &even, int l, int r) {
- int ol,orr,el,er;
- pnode oa,ob,ea,eb;
- if (l&1) {
- ol=(l+1)/2; orr=r/2;
- el=(l+1)/2; er=r/2;
- }
- else {
- ol=l/2+1; orr=r/2+1;
- el=l/2; er=r/2;
- }
- split(odd,odd,oa,ol,0);
- split(oa,oa,ob,orr-ol+2,0);
- split(even,even,ea,el,0);
- split(ea,ea,eb,er-el+2,0);
- merge(odd,odd,ea);
- merge(odd,odd,ob);
- merge(even,even,oa);
- merge(even,even,eb);
- upd(odd); upd(even);
- }
- long long getsum(pnode odd, pnode even, int l, int r) {
- int ol,orr,el,er;
- long long ans;
- pnode oa,ob,ea,eb;
- if (l&1) {
- ol=(l+1)/2;
- el=(l+1)/2;
- }
- else {
- ol=l/2+1;
- el=l/2;
- }
- if (r&1) {
- orr=r/2+1;
- er=r/2;
- }
- else {
- orr=r/2;
- er=r/2;
- }
- split(odd,odd,oa,ol,0);
- split(oa,oa,ob,orr-ol+2,0);
- split(even,even,ea,el,0);
- split(ea,ea,eb,er-el+2,0);
- ans=sum(ea)+sum(oa);
- merge(odd,odd,oa);
- merge(odd,odd,ob);
- merge(even,even,ea);
- merge(even,even,eb);
- // 1 2 3 4 5
- // 1 3 2 5 4
- return ans;
- }
- void output(pnode t) {
- if (t) {
- output(t->l);
- printf("%d ",t->val);
- output(t->r);
- }
- }
- int n,m,q,l,r,test=0;
- pnode odd=NULL,even=NULL,add;
- int main() {
- //freopen("input.txt","r",stdin);
- //freopen("output.txt","w",stdout);
- odd = NULL; even = NULL;
- scanf("%d %d\n", &n, &m);
- for (int i = 1; i <= n; i++) {
- int x;
- scanf("%d", &x);
- add = new node(x, rand());
- if (i & 1)
- merge(odd, odd, add);
- else
- merge(even, even, add);
- }
- for (int i = 1; i <= m; i++) {
- int q, l, r;
- scanf("%d %d %d\n", &q, &l, &r);
- if (q == 1) {
- swapper(odd, even, l, r);
- //output(odd); output(even);
- //printf("\n");
- }
- else {
- //cout<<getsum(odd,even,l,r)<<endl;
- printf("%lld\n", getsum(odd, even, l, r));
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment