码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1251: 序列终结者

时间:2015-08-21 11:07:18      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

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。

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 }

 

 

bzoj1251: 序列终结者

标签:

原文地址:http://www.cnblogs.com/chenyushuo/p/4747105.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!