bzoj1251: 序列终结者
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。
fhq treap裸题(也是splay裸题)
PS:bzoj不能用time(0)
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #define maxn 50005 7 using namespace std; 8 typedef pair<int,int> pii; 9 char ch; 10 int n,m,root,op,l,r,x; 11 bool ok; 12 void read(int &x){ 13 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; 14 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); 15 if (ok) x=-x; 16 } 17 int random(int mod){return rand()*rand()%mod+1;} 18 struct fhq_treap{ 19 int son[maxn][2],add[maxn],rev[maxn],max_val[maxn],val[maxn],siz[maxn]; 20 void init(){for (int i=1;i<=n;i++) siz[i]=1;} 21 void Rev(int a){rev[a]^=1;} 22 void inc(int a,int v){add[a]+=v,max_val[a]+=v,val[a]+=v;} 23 void pushdown(int a){ 24 if (rev[a]) Rev(son[a][0]),Rev(son[a][1]),rev[a]=0,swap(son[a][0],son[a][1]); 25 if (add[a]) inc(son[a][0],add[a]),inc(son[a][1],add[a]),add[a]=0; 26 } 27 void update(int a){ 28 siz[a]=1,max_val[a]=val[a]; 29 if (son[a][0]) siz[a]+=siz[son[a][0]],max_val[a]=max(max_val[a],max_val[son[a][0]]); 30 if (son[a][1]) siz[a]+=siz[son[a][1]],max_val[a]=max(max_val[a],max_val[son[a][1]]); 31 } 32 int merge(int a,int b){ 33 if (!a||!b) return a+b; 34 if (random(siz[a]+siz[b])<=siz[a]){ 35 pushdown(a),son[a][1]=merge(son[a][1],b),update(a); 36 return a; 37 } 38 else{ 39 pushdown(b),son[b][0]=merge(a,son[b][0]),update(b); 40 return b; 41 } 42 } 43 pii split(int a,int k){ 44 if (!k) return make_pair(0,a); 45 if (siz[a]==k) return make_pair(a,0); 46 pushdown(a); 47 if (siz[son[a][0]]>=k){ 48 pii tmp=split(son[a][0],k); 49 son[a][0]=tmp.second,update(a); 50 return make_pair(tmp.first,a); 51 } 52 else{ 53 pii tmp=split(son[a][1],k-siz[son[a][0]]-1); 54 son[a][1]=tmp.first,update(a); 55 return make_pair(a,tmp.second); 56 } 57 } 58 }T; 59 void add(int l,int r,int x){ 60 pii t; 61 int a,b,c; 62 t=T.split(root,r); 63 c=t.second; 64 t=T.split(t.first,l-1); 65 a=t.first,b=t.second; 66 T.inc(b,x); 67 root=T.merge(a,b),root=T.merge(root,c); 68 } 69 void rev(int l,int r){ 70 pii t; 71 int a,b,c; 72 t=T.split(root,r); 73 c=t.second; 74 t=T.split(t.first,l-1); 75 a=t.first,b=t.second; 76 T.Rev(b); 77 root=T.merge(a,b),root=T.merge(root,c); 78 } 79 void query(int l,int r){ 80 pii t; 81 int a,b,c; 82 t=T.split(root,r); 83 c=t.second; 84 t=T.split(t.first,l-1); 85 a=t.first,b=t.second; 86 printf("%d\n",T.max_val[b]); 87 root=T.merge(a,b),root=T.merge(root,c); 88 } 89 int main(){ 90 srand('f'+'u'+'c'+'k'+'w'+'m'+'j'); 91 read(n),read(m),T.init(),root=1; 92 for (int i=2;i<=n;i++) root=T.merge(root,i); 93 while (m--){ 94 read(op),read(l),read(r); 95 if (op==1) read(x),add(l,r,x); 96 else if (op==2) rev(l,r); 97 else query(l,r); 98 } 99 return 0; 100 }