Bzoj1251 序列终结者
Submit: 3788 Solved: 1591
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
Splay基本操作
1 #include<algorithm> 2 #include<cstring> 3 #include<cmath> 4 #include<cstdio> 5 using namespace std; 6 const int mxn=50010; 7 int read(){ 8 int x=0,f=1;char ch=getchar(); 9 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 10 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 11 return x*f; 12 } 13 struct node{ 14 int ch[2]; 15 int fa,size; 16 int mx,v,mak; 17 bool rev; 18 }t[mxn]; 19 int id[mxn]; 20 int rt; 21 int n,m; 22 void pushdown(int x){ 23 int lc=t[x].ch[0];int rc=t[x].ch[1]; 24 if(t[x].mak){//标记下传 25 if(lc){t[lc].mak+=t[x].mak;t[lc].mx+=t[x].mak;t[lc].v+=t[x].mak;} 26 if(rc){t[rc].mak+=t[x].mak;t[rc].mx+=t[x].mak;t[rc].v+=t[x].mak;} 27 t[x].mak=0; 28 } 29 if(t[x].rev){//区间翻转 30 swap(t[x].ch[0],t[x].ch[1]);t[lc].rev^=1;t[rc].rev^=1; 31 t[x].rev=0; 32 } 33 return; 34 } 35 void pushup(int x){ 36 int lc=t[x].ch[0];int rc=t[x].ch[1]; 37 t[x].mx=max(t[lc].mx,t[rc].mx); 38 t[x].mx=max(t[x].mx,t[x].v); 39 t[x].size=t[lc].size+t[rc].size+1; 40 return; 41 } 42 void rotate(int x,int &k){ 43 int y=t[x].fa;int z=t[y].fa,lc,rc; 44 if(t[y].ch[0]==x)lc=0;else lc=1; 45 rc=lc^1; 46 if(y==k)k=x; 47 else { 48 if(t[z].ch[0]==y) t[z].ch[0]=x; 49 else t[z].ch[1]=x; 50 } 51 t[x].fa=z;t[y].fa=x; t[t[x].ch[rc]].fa=y; 52 t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y; 53 pushup(y); 54 pushup(x); 55 } 56 void Splay(int x,int &k){ 57 while(x!=k){ 58 int y=t[x].fa;int z=t[y].fa; 59 if(y!=k){ 60 if( (t[z].ch[0]==y)^(t[y].ch[0]==x) )rotate(x,k); 61 else rotate(y,k); 62 } 63 rotate(x,k); 64 } 65 return; 66 } 67 void Build(int l,int r,int fa){ 68 if(l>r)return; 69 int now=id[l],last=id[fa]; 70 if(l==r){ 71 t[now].fa=last; 72 t[now].size=1; 73 if(l<fa) t[fa].ch[0]=now; 74 else t[fa].ch[1]=now; 75 return; 76 } 77 int mid=(l+r)>>1;now=id[mid]; 78 Build(l,mid-1,mid);Build(mid+1,r,mid); 79 t[now].fa=last; 80 pushup(now); 81 if(mid<fa) t[last].ch[0]=now; 82 else t[last].ch[1]=now; 83 return; 84 } 85 int find(int x,int rank){ 86 if(t[x].mak || t[x].rev)pushdown(x); 87 int lc=t[x].ch[0];int rc=t[x].ch[1]; 88 if(t[lc].size+1==rank)return x; 89 else if(t[lc].size>=rank)return find(lc,rank); 90 else return find(rc,rank-t[lc].size-1); 91 } 92 93 void add(int L,int R,int v){ 94 int x=find(rt,L);int y=find(rt,R+2); 95 Splay(x,rt);Splay(y,t[x].ch[1]); 96 int z=t[y].ch[0]; 97 t[z].mak+=v;t[z].v+=v;t[z].mx+=v; 98 return; 99 } 100 void rev(int L,int R){ 101 int x=find(rt,L),y=find(rt,R+2); 102 Splay(x,rt);Splay(y,t[x].ch[1]); 103 t[t[y].ch[0]].rev^=1; 104 return; 105 } 106 int query(int L,int R){ 107 int x=find(rt,L),y=find(rt,R+2); 108 Splay(x,rt);Splay(y,t[x].ch[1]); 109 return t[t[y].ch[0]].mx; 110 } 111 int main() 112 { 113 t[0].mx=-1e9; 114 int i,j,k,x,y; 115 n=read();m=read(); 116 for(i=1;i<=n+2;i++)id[i]=i; 117 Build(1,n+2,0);rt=(n+3)>>1; 118 int L,R; 119 while(m--){ 120 k=read();L=read();R=read(); 121 switch(k){ 122 case 1:{x=read();add(L,R,x);break;} 123 case 2:{rev(L,R);break;} 124 case 3:{printf("%d\n",query(L,R));break;} 125 } 126 } 127 return 0; 128 }
本文为博主原创文章,转载请注明出处。