【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 }

时间: 2024-10-11 04:21:08

【BZOJ】【1251】序列终结者的相关文章

伸展树复习 (bzoj 1251 序列终结者)

本来要看LCT的,确发现自己弱得连splay都忘记了,复习一发,顺便重写一发 关键点: 1. 伸展树为左小右大的二叉树,所以旋转操作不会影响树的性质 2. 区间操作为: int u = select(L - 1), v = select(R + 1); splay(u, 0); splay(v, u); //通过旋转操作把询问的区间聚集到根的右子树的左子树下 因为伸展树为左小右大的二叉树,旋转操作后的所以对于闭区间[L, R]之间的所有元素都聚集在根的右子树的左子树下 因为闭区间[L, R],

BZOJ 1251: 序列终结者( splay )

先orz一下clj...我的splay跟着他写的... 这道题很普通的splay我调了这么久 T T , 就是因为 null 的值初始化为0 , 结果就挂了... -------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream>

bzoj 1251: 序列终结者 2011-12-20

1251: 序列终结者Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 650  Solved: 277[Submit][Status][Discuss]Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可

BZOJ 1251 序列终结者(Splay)

题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思.这道题目 就叫序列终结者吧.[问题描述] 给定一个长度为N的序列,每个序列的元素是一个整数(废话).要支持以下三种操作: 1. 将 [L, R] 这个区间内的所有数加上 V. 2. 将 [

Bzoj 1251: 序列终结者 (Splay 模板题)

题面(太裸太裸,不看也罢) 就是维护一个区间加,区间翻转和区间最大值. 贴一个风格以后可以一直用 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 100000 6 #define XX getchar() 7 using namespace std; 8 int ch[N][2],fa[N],rev[N],ad[N],b

BZOJ 1251 序列终结者

注意pushup的时候要先判断有没有左右儿子.因为有负数,所以这个可能会出bug. 很烦带标记的数据结构啊...秉承这样一个思路:只要局部的标记下方吗没有问题,整个程序应该都不会怎么出问题. 也就是思路要顺着程序而不是顺着标记. #include<iostream> #include<cstdio> #include<cstring> #define maxn 100500 #define inf 1000000007 using namespace std; int

【BZOJ】1251: 序列终结者(splay)

http://www.lydsy.com/JudgeOnline/problem.php?id=1251 不行..为什么写个splay老是犯逗,这次又是null的mx没有赋值-maxlongint... #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #inc

【BZOJ】1251: 序列终结者

[题意]给定含有n个0的的数列. 1.区间加值 2.区间翻转 3.区间求最大值 [算法]平衡树(fhq-treap) 需要特别注意的是: 1.使0点对全局无影响并全程保持(例如求max,t[0].mx=-inf) 2.平衡树和线段树的上传区别在于要考虑本身这个点. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100010; struc

BZOJ1251&#183;序列终结者

好像不能附传送门了..这是道sb权限题.. 1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MB Description 网 上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思.这道题目 就叫序列终