BZOJ1251序列终结者 Splay
Posted DMoon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1251序列终结者 Splay相关的知识,希望对你有一定的参考价值。
一道模板题,一直没发现自己的快速读入读不了负数,我竟然能活到现在真是万幸。
1 #include <iostream> 2 #include <cstdio> 3 #define inf -0x7fffffff 4 #define N 50010 5 using namespace std; 6 struct SplayNode 7 { 8 SplayNode(); 9 SplayNode *fa,*ch[2]; 10 //SplayNode(int x); 11 int data,maxn,size,add; 12 bool rev; 13 void push(); 14 bool chr() {return this==fa->ch[1];} 15 void updata() 16 { 17 size=ch[0]->size+ch[1]->size+1; 18 maxn=max(max(ch[0]->maxn,ch[1]->maxn),data); 19 } 20 void setc(SplayNode *x,int t) {this->ch[t]=x; x->fa=this;} 21 }*null; 22 SplayNode::SplayNode() {fa=ch[1]=ch[0]=null; rev=0;data=add=size=0; maxn=inf;} 23 void SplayNode::push() 24 { 25 if (rev) 26 { 27 if (ch[0]!=null) ch[0]->rev^=1; 28 if (ch[1]!=null) ch[1]->rev^=1; 29 swap(ch[0],ch[1]); 30 rev=0; 31 } 32 if (add!=0) 33 { 34 if (ch[1]!=null) 35 { 36 ch[1]->add+=add; 37 ch[1]->maxn+=add; 38 ch[1]->data+=add; 39 } 40 if (ch[0]!=null) 41 { 42 ch[0]->add+=add; 43 ch[0]->maxn+=add; 44 ch[0]->data+=add; 45 } 46 add=0; 47 } 48 } 49 int n,m; 50 //inline int read() {int ans=0; char c; while ((c=getchar())==‘\r‘ || c==‘\n‘ || c==‘ ‘); ans=c-‘0‘; while (isdigit(c=getchar())) ans=ans*10+c-‘0‘; return ans;} 51 namespace Splay 52 { 53 SplayNode *Root; 54 SplayNode pool[N]; 55 int poolnum=0; 56 SplayNode *NewNode() 57 { 58 poolnum++; 59 pool[poolnum]=SplayNode(); 60 return &pool[poolnum]; 61 } 62 SplayNode *BuildTree(int l,int r) 63 { 64 if (l>r) return null; 65 SplayNode *re=NewNode(); 66 int mid=(l+r)>>1; 67 re->data=0; 68 re->ch[0]=BuildTree(l,mid-1); 69 re->ch[1]=BuildTree(mid+1,r); 70 re->ch[0]->fa=re; 71 re->ch[1]->fa=re; 72 re->updata(); 73 return re; 74 } 75 void rotate(SplayNode *x) 76 { 77 SplayNode *r=x->fa; 78 if (x==null || r==null) return; 79 int t=x->chr(); 80 x->push(); r->push(); 81 if (r->fa==null) x->fa=r->fa,Root=x; 82 else r->fa->setc(x,r->chr()); 83 r->setc(x->ch[t^1],t); 84 x->setc(r,!t); 85 r->updata(); 86 x->updata(); 87 } 88 void splay(SplayNode *x,SplayNode *y) 89 { 90 for (;x->fa!=y;rotate(x)) 91 if (x->fa->fa!=y) 92 if (x->chr()==x->fa->chr()) rotate(x->fa); 93 else rotate(x); 94 } 95 SplayNode *Kth(int k) 96 { 97 SplayNode *r=Root; 98 while (r!=null) 99 { 100 r->push(); 101 if (k<=r->ch[0]->size) r=r->ch[0]; 102 else if (k==r->ch[0]->size+1) return r; 103 else 104 { 105 k-=r->ch[0]->size+1; 106 r=r->ch[1]; 107 } 108 } 109 return null; 110 } 111 void reverse(int l,int r) 112 { 113 SplayNode *p=Kth(l); 114 SplayNode *s=Kth(r+2); 115 p->push(); 116 splay(p,null); 117 s->push(); 118 splay(s,p); 119 s->ch[0]->rev^=1; 120 } 121 void Add(int l,int r,int v) 122 { 123 SplayNode *p=Kth(l); 124 SplayNode *s=Kth(r+2); 125 p->push(); 126 splay(p,null); 127 s->push(); 128 splay(s,p); 129 s->ch[0]->add+=v; 130 s->ch[0]->data+=v; 131 s->ch[0]->maxn+=v; 132 } 133 void query(int l,int r) 134 { 135 SplayNode *p=Kth(l); 136 SplayNode *s=Kth(r+2); 137 p->push(); 138 splay(p,null); 139 s->push(); 140 splay(s,p); 141 printf("%d\n",s->ch[0]->maxn); 142 } 143 } 144 void init() {null=Splay::NewNode(); *null=SplayNode(); Splay::Root=Splay::BuildTree(0,n+1);} 145 int main() 146 { 147 scanf("%d%d",&n,&m); 148 init(); 149 //for (int i=1;i<=n;i++) a[i]=read(); 150 //Splay::BuildTree(1,n); 151 for (int i=1;i<=m;i++) 152 { 153 int temp,x,y; 154 scanf("%d%d%d",&temp,&x,&y); 155 //temp=read(); x=read(); y=read(); 156 if (temp==1) 157 { 158 int v; 159 scanf("%d",&v); 160 Splay::Add(x,y,v); 161 } 162 if (temp==2) Splay::reverse(x,y); 163 if (temp==3) Splay::query(x,y); 164 } 165 return 0; 166 }
Description
网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列 要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。 【问题描述】 给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V。 2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1。 3. 求[L,R]这个区间中的最大值。 最开始所有元素都是0。
Input
第一行两个整数N,M。M为操作个数。 以下M行,每行最多四个整数,依次为K,L,R,V。K表示是第几种操作,如果不是第1种操作则K后面只有两个数。
Output
对于每个第3种操作,给出正确的回答。
Sample Input
4 4
1 1 3 2
1 2 4 -1
2 1 3
3 2 4
1 1 3 2
1 2 4 -1
2 1 3
3 2 4
Sample Output
2
【数据范围】
N<=50000,M<=100000。
【数据范围】
N<=50000,M<=100000。
HINT
Source
以上是关于BZOJ1251序列终结者 Splay的主要内容,如果未能解决你的问题,请参考以下文章