bzoj 1251 简单伸展树

来源:互联网 发布:java文档预览 编辑:程序博客网 时间:2024/06/05 15:17

基本操作 翻转 成段加上一个数 求区间最值

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#include<set>#include<cstring>#include<vector>using namespace std;#define L p->ch[0]#define R p->ch[1]#define KeyTree root->ch[1]->ch[0]typedef long long LL;const int maxn = 611111;const int INF = 0x77ffffff;struct Node {int val, Max, add;int sz;bool rev;Node *pre, *ch[2];};int a[maxn];struct SplayTree {Node *null, *root, data[maxn];int cnt;Node *NewNode(int x) {Node *p = &data[cnt++];p->val = p->Max = x;p->sz = 1;p->add = 0;L=R=p->pre=null;return p;}void pushup(Node *p) {p->sz = (L->sz)+(R->sz) + 1;p->Max=p->val;if(L!=null) {p->Max=max(p->Max,L->Max);}if(R!=null) {p->Max=max(p->Max,R->Max);}}void pushdown(Node *p) {if(p==null) {return;}if(p->rev) {swap(L,R);L->rev^=1;R->rev^=1;p->rev=0;}if(p->add) {L->add+=p->add;L->val+=p->add;L->Max+=p->add;R->add+=p->add;R->val+=p->add;R->Max+=p->add;p->add=0;}}void init() {cnt=0;null=NewNode(-INF);null->sz=0;root=NewNode(-INF);root->ch[1]=NewNode(-INF);root->ch[1]->pre=root;pushup(root);}void rotate(Node *x,int c) {Node *y=x->pre;pushdown(y);pushdown(x);y->ch[!c]=x->ch[c];if(x->ch[c]!=null) {x->ch[c]->pre=y;}x->pre=y->pre;if(y->pre!=null) {int f=(y->pre->ch[1]==y);y->pre->ch[f]=x;}x->ch[c]=y;y->pre=x;pushup(y);}void splay(Node *x,Node *f) {pushdown(x);while(x->pre!=f) {if(x->pre->pre==f) {rotate(x,x->pre->ch[0]==x);} else {Node *y=x->pre;Node *z=y->pre;if(z->ch[0]==y) {if(y->ch[0]==x) {rotate(y,1),rotate(x,1);} else {rotate(x,0),rotate(x,1);}} else {if(y->ch[1]==x) {rotate(y,0),rotate(x,0);} else {rotate(x,1),rotate(x,0);}}}}if(f==null) {root=x;}pushup(x);}void RotateTo(int k,Node *f) {int tmp;Node *t=root;pushdown(t);while(true) {tmp=t->ch[0]->sz;if(tmp + 1==k) {break;}if(k<=tmp) {t=t->ch[0];} else {k-=tmp + 1;t=t->ch[1];}pushdown(t);}splay(t,f);}Node *build(int l,int r) {if(l>r) {return null;}int m=(l+r)>>1;Node *p=NewNode(a[m]);p->ch[0]=build(l,m-1);if(p->ch[0]!=null) {p->ch[0]->pre=p;}p->ch[1]=build(m+1,r);if(p->ch[1]!=null) {p->ch[1]->pre=p;}pushup(p);return p;}void add(int l,int r,int v) {RotateTo(l,null);RotateTo(r,root);KeyTree->add+=v;KeyTree->val+=v;KeyTree->Max+=v;pushup(root->ch[1]);pushup(root);}void flip(int l,int r) {RotateTo(l,null);RotateTo(r,root);KeyTree->rev^=1;}int Max(int l,int r) {RotateTo(l,null);RotateTo(r,root);return KeyTree->Max;}void Travel(Node *p) {pushdown(p);if(L!=null) {Travel(L);}printf("%d ",p->val);if(R!=null) {Travel(R);}}void debug() {Travel(root);puts("");}}spt;inline void readT(int &ret) {char ch, pre = 0;while (ch = getchar(), ch < '0' || ch > '9')pre = ch;ret = ch ^ 0x30;while (ch = getchar(), ch >= '0' && ch <= '9')ret = ret*10 + (ch ^ 0x30);if (pre == '-')ret *= -1;}int main() {int n, i, m;//scanf("%d%d", &n, &m);readT(n);readT(m);spt.init();Node* tmp = spt.build(1, n);spt.root->ch[1]->ch[0] = tmp;tmp->pre = spt.root->ch[1];spt.pushup(spt.root->ch[1]);spt.pushup(spt.root);//spt.debug();for (i = 0; i < m; ++i) {int t;readT(t);int l, r, v;if (t == 1) {readT(l);readT(r);readT(v);++l, ++r;spt.add(l - 1, r + 1, v);}if (t == 2) {readT(l);readT(r);++l, ++r;spt.flip(l - 1, r + 1);}if (t == 3) {readT(l);readT(r);++l, ++r;//spt.debug();printf("%d\n", spt.Max(l - 1, r + 1));}//spt.debug();}return 0;}/* 17 11 1 8 10 2 1 6 10 -1 1 3 7 15 2 1 15 1 4 17 -2 3 5 10 2 2 10 3 3 8 2 6 10 2 1 10 3 1 10  */


原创粉丝点击