Bzoj1251 序列终结者

Time Limit: 20 Sec  Memory Limit: 162 MB
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

Sample Output

2
【数据范围】
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 }

 

posted @ 2016-12-27 17:12  SilverNebula  阅读(161)  评论(0编辑  收藏  举报
AmazingCounters.com