AmazingCounters.com

BZOJ1251·序列终结者

好像不能附传送门了。。这是道sb权限题。。

1251: 序列终结者

Time Limit: 20 Sec  Memory Limit: 162 MB

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。

 

很简单的splay,维护区间最大值,翻转信息。
学习了链式建树,但是后来实验发现nlogn建树和链式建树效率基本相同(链式建树后面需要反转的次数较多)
HINT:T[0].Max = -2147483647,这点很重要。。如果某点没有前驱,那么更新最大值的时候。。→_→
Codes:
  1 #include <set>
  2 #include <queue>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <algorithm>
  9 using namespace std;
 10 const int N = 50010;
 11 #define fa(i) T[i].p
 12 #define L(i) T[i].s[0]
 13 #define R(i) T[i].s[1]
 14 #define Loc(i) (T[fa(i)].s[1]==i)
 15 #define Sets(a,b,c) {T[a].s[c] = b; fa(b) = a;}
 16 #define For(i,n) for(int i=1;i<=n;i++)
 17 #define Rep(i,l,r) for(int i=l;i<=r;i++)
 18 
 19 struct tnode{
 20     int s[2],size,p,markp,markr,Max,v;
 21 }T[N];
 22 
 23 int n,m,root = 1,tot;
 24 int l,r,op,delta;
 25 
 26 void Pushdown(int i){
 27     if(T[i].markp){
 28         if(L(i))  {T[L(i)].markp+=T[i].markp;T[L(i)].Max  +=T[i].markp;T[L(i)].v+=T[i].markp;}
 29         if(R(i))  {T[R(i)].Max  +=T[i].markp;T[R(i)].markp+=T[i].markp;T[R(i)].v+=T[i].markp;}
 30         T[i].markp = 0;
 31     }
 32     if(T[i].markr){
 33         if(L(i)) T[L(i)].markr ^= 1;
 34         if(R(i)) T[R(i)].markr ^= 1;
 35         swap(L(i),R(i));
 36         T[i].markr = 0;
 37     }
 38 }
 39 
 40 void Rot(int x){
 41     int y = fa(x) , z = fa(y);
 42     int lx = Loc(x) , ly = Loc(y);
 43     Pushdown(y);Pushdown(x);
 44     Sets(y,T[x].s[lx^1],lx);
 45     Sets(z,x,ly);
 46     Sets(x,y,lx^1);
 47     T[y].size = T[L(y)].size + T[R(y)].size + 1;
 48     T[y].Max  = max(max(T[L(y)].Max,T[R(y)].Max),T[y].v);
 49 }
 50 
 51 void Splay(int i,int goal){
 52     while(fa(i)!=goal){
 53         if(fa(fa(i))!=goal) Rot(fa(i));
 54         Rot(i);
 55     }
 56     if(!goal) root = i;
 57     T[i].size = T[L(i)].size + T[R(i)].size + 1;
 58     T[i].Max  = max(max(T[L(i)].Max,T[R(i)].Max),T[i].v);
 59 }
 60 
 61 inline int Rank(int i,int rank){
 62     Pushdown(i);
 63     if(T[L(i)].size + 1 == rank)   return i;
 64     else  if(T[L(i)].size >= rank) return Rank(L(i),rank);
 65     else                           return Rank(R(i),rank-T[L(i)].size - 1);
 66 }
 67 
 68 /*inline void Build(){//链式建树 
 69     For(i,n+2) {
 70         T[i].p=i-1;
 71         T[i].s[1]=i+1;
 72         T[i].size=n+3-i;
 73         T[i].v=T[i].s[0]=T[i].markr=T[i].markp=T[i].Max=0;
 74     }
 75     T[n+2].s[1]=0;
 76     T[0].Max=-2147483647;    
 77 }*/ 
 78 
 79 inline void Build(int l,int r,int &i,int p){
 80     if(l>r) return;
 81     int m = (l+r)>>1;
 82     i=++tot;
 83     T[i].p = p; T[i].size = 1;T[i].markp = T[i].markr = T[i].v = T[i].Max = 0;    
 84     Build(l,m-1,L(i),i);Build(m+1,r,R(i),i);
 85     T[i].size = T[L(i)].size + T[R(i)].size + 1;
 86 }
 87 
 88 inline void Reserve(int l,int r){
 89     Splay(Rank(root,l),0);
 90     Splay(Rank(root,r+2),root);
 91     T[L(R(root))].markr ^= 1;
 92 }
 93 
 94 inline void Plus(int l,int r,int delta){
 95     Splay(Rank(root,l),0);
 96     Splay(Rank(root,r+2),root);
 97     T[L(R(root))].markp+=delta;
 98     T[L(R(root))].Max += delta;
 99     T[L(R(root))].v+=delta;
100 }
101 
102 inline void Query(int l,int r){
103     Splay(Rank(root,l),0);
104     Splay(Rank(root,r+2),root);
105     printf("%d\n",T[L(R(root))].Max);
106 }
107 
108 int main(){
109     scanf("%d%d",&n,&m);
110     Build(0,n+1,root,0);T[0].Max = -2147483647;
111    // Build();
112     For(i,m){
113         scanf("%d",&op);
114         if(op==1) {
115             scanf("%d%d%d",&l,&r,&delta);
116             Plus(l,r,delta);
117         }
118         else{
119             scanf("%d%d",&l,&r);
120             if(op==2) Reserve(l,r);
121             else      Query(l,r);    
122         }
123     }
124     return 0;
125 }

 

posted @ 2014-07-23 11:15  ZJDx1998  阅读(451)  评论(0编辑  收藏  举报