【BZOJ】【1251】序列终结者
Splay
还是splay序列维护,这题我WA了的原因是:在Push_up的时候,当前子树的max我是直接取的L、R和v[x]的最大值,但是如果没有左/右儿子,默认是会访问0号结点的mx值,而这个值没有初始化成-INF,所以就会导致所有负max值全部变为0……
1 /************************************************************** 2 Problem: 1251 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:8692 ms 7 Memory:4888 kb 8 ****************************************************************/ 9 10 //BZOJ 1251 11 #include<vector> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 inline int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 25 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 26 return v*sign; 27 } 28 const int N=1e5+10,INF=~0u>>2; 29 typedef long long LL; 30 /******************tamplate*********************/ 31 int a[N],n,m; 32 int c[N][2],fa[N],v[N],size[N],add[N],mx[N],tot,root; 33 bool rev[N]; 34 #define L c[x][0] 35 #define R c[x][1] 36 void Push_down(int x){ 37 if (rev[x]){ 38 rev[L]^=1; rev[R]^=1; 39 swap(L,R); rev[x]=0; 40 } 41 if (add[x]){ 42 if (L) mx[L]+=add[x]; v[L]+=add[x]; add[L]+=add[x]; 43 if (R) mx[R]+=add[x]; v[R]+=add[x]; add[R]+=add[x]; 44 add[x]=0; 45 } 46 } 47 void Push_up(int x){ 48 mx[x]=max(v[x],max(mx[L],mx[R])); 49 size[x]=size[L]+size[R]+1; 50 } 51 void New_node(int &x,int f,int key){ 52 x=++tot; 53 fa[x]=f; mx[x]=v[x]=key; 54 L=R=rev[x]=add[x]=0; 55 size[x]=1; 56 } 57 void Build(int &x,int f,int l,int r){ 58 if (l>r) return; 59 int m=l+r>>1; 60 New_node(x,f,a[m]); 61 Build(L,x,l,m-1); 62 Build(R,x,m+1,r); 63 Push_up(x); 64 } 65 void Rotate(int x){ 66 int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1; 67 c[z][c[z][1]==y]=x; 68 fa[x]=z; fa[y]=x; fa[c[x][r]]=y; 69 c[y][l]=c[x][r]; c[x][r]=y; 70 Push_up(y); 71 } 72 int st[N],top; 73 void Preview(int x){ 74 top=0; st[++top]=x; 75 for(;fa[x];x=fa[x]) 76 st[++top]=fa[x]; 77 D(i,top,1) Push_down(st[i]); 78 } 79 void splay(int x,int s=0){ 80 int y; 81 for(Preview(x);fa[x]!=s;Rotate(x)) 82 if (fa[y=fa[x]]!=s) 83 Rotate( c[y][1]==x^c[fa[y]][1]==y ? x : y); 84 Push_up(x); 85 if (!s) root=x; 86 } 87 int kth(int x,int k){ 88 Push_down(x); 89 if (size[L]+1==k) return x; 90 else if (size[L]>=k) return kth(L,k); 91 else return kth(R,k-size[L]-1); 92 } 93 int main(){ 94 #ifndef ONLINE_JUDGE 95 freopen("1251.in","r",stdin); 96 freopen("1251.out","w",stdout); 97 #endif 98 n=getint(); m=getint(); 99 a[0]=a[n+1]=-INF; mx[0]=-INF; 100 Build(root,0,0,n+1); 101 int cmd,x,y,z,pos; 102 F(i,1,m){ 103 cmd=getint(); x=getint(); y=getint(); 104 splay(kth(root,x)); splay(kth(root,y+2),root); 105 pos=c[c[root][1]][0]; 106 if (cmd==1){ 107 z=getint(); 108 add[pos]+=z; v[pos]+=z; mx[pos]+=z; 109 splay(pos); 110 }else if (cmd==2){ 111 rev[pos]^=1; 112 splay(pos); 113 }else if (cmd==3){ 114 printf("%d\n",mx[pos]); 115 splay(pos); 116 } 117 } 118 return 0; 119 }
1251: 序列终结者
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 2798 Solved: 1115
[Submit][Status][Discuss]
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。