bzoj 1251 序列终结者
来源:互联网 发布:苹果电脑炒股软件 编辑:程序博客网 时间:2024/05/16 15:17
1251: 序列终结者
Time Limit: 20 Sec Memory Limit: 162 MB
Submit: 4170 Solved: 1752
[Submit][Status][Discuss]
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。
【分析】
水题…大题的子问题…更新了一种区间翻转的pushdown写法,感觉这样比较清爽吧…
(ch数组开成ch[mxn][0]也是没谁了…为啥不提示我RE呢)
【代码】
//bzoj 序列终结者 #include<iostream>#include<cstring>#include<cstdio>#define ll long long#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=100005;int n,m,root,sz;int a[mxn],f[mxn],key[mxn],mx[mxn],size[mxn],ch[mxn][2],add[mxn],mark[mxn];inline int get(int x){ if(ch[f[x]][1]==x) return 1;return 0;}inline void update(int x){ if(!x) return; size[x]=1; if(ch[x][0]) size[x]+=size[ch[x][0]]; if(ch[x][1]) size[x]+=size[ch[x][1]]; mx[x]=key[x]; if(ch[x][0]) mx[x]=max(mx[x],mx[ch[x][0]]); if(ch[x][1]) mx[x]=max(mx[x],mx[ch[x][1]]);}inline void ADD(int now,int w){ if(!now) return; key[now]+=w,mx[now]+=w,add[now]+=w;}inline void reverse(int now){ if(!now) return; swap(ch[now][0],ch[now][1]); mark[now]^=1;}inline void pushdown(int now){ if(!now) return; int l=ch[now][0],r=ch[now][1]; if(add[now]) { if(l) ADD(l,add[now]); if(r) ADD(r,add[now]); add[now]=0; } if(mark[now]) { if(l) reverse(l); if(r) reverse(r); mark[now]=0; }}inline void rotate(int now){ if(!now) return; pushdown(now); int fa=f[now],fafa=f[fa],which=get(now); ch[fa][which]=ch[now][which^1],f[ch[fa][which]]=fa; ch[now][which^1]=fa,f[fa]=now; f[now]=fafa; if(fafa) ch[fafa][ch[fafa][1]==fa]=now; update(fa),update(now);}inline void splay(int x,int lastfa){ for(int fa;(fa=f[x])!=lastfa;rotate(x)) if(f[fa]!=lastfa) rotate(get(x)==get(fa)?fa:x); if(!lastfa) root=x;}inline int number(int x){ int now=root; while(1) { pushdown(now); if(ch[now][0] && x<=size[ch[now][0]]) now=ch[now][0]; else { if(x==size[ch[now][0]]+1) return now; x=x-size[ch[now][0]]-1; now=ch[now][1];pushdown(now); } }}inline int build(int fa,int l,int r){ if(l>r) return 0; int now=++sz,mid=(l+r)>>1; f[now]=fa,size[now]=1; ch[now][0]=build(now,l,mid-1); ch[now][1]=build(now,mid+1,r); update(now); return now;}int main(){ int i,j,opt,x,y,z,w; scanf("%d%d",&n,&m); root=build(0,1,n+2); while(m--) { scanf("%d",&opt); if(opt==1) //区间加 { scanf("%d%d%d",&x,&y,&w); x++,y++; x=number(x-1),y=number(y+1); splay(x,0),splay(y,x); ADD(ch[y][0],w); } if(opt==2) //区间翻转 { scanf("%d%d",&x,&y); x++,y++; x=number(x-1),y=number(y+1); splay(x,0),splay(y,x); reverse(ch[y][0]); } if(opt==3) //区间询问最大值 { scanf("%d%d",&x,&y); x++,y++; x=number(x-1),y=number(y+1); splay(x,0),splay(y,x); printf("%d\n",mx[ch[y][0]]); } } return 0;}/*4 41 1 3 23 2 4*/
0 0
- BZOJ 1251: 序列终结者
- 【BZOJ 1251】 序列终结者
- bzoj 1251: 序列终结者
- bzoj 1251 序列终结者
- 【bzoj 1251】序列终结者
- [bzoj 1251]序列终结者
- [BZOJ 1251] 序列终结者
- BZOJ 1251 序列终结者
- BZOJ 1251 序列终结者
- 【BZOJ 1251】序列终结者
- bzoj 1251 序列终结者
- BZOJ 1251 序列终结者
- BZOJ 1251 序列终结者
- BZOJ 1251: 序列终结者
- BZOJ 1251 序列终结者 Splay
- BZOJ 1251 序列终结者 Splay
- bzoj 1251/tyvj p2195 序列终结者
- BZOJ 1251 序列终结者 Splay
- 什么是Java异常?
- windows下C++的中文块注释问题
- PHP 腾讯云 配置 Apache + PHP
- WebView中文本输入框,点击弹出输入框后,崩溃
- RobotFramework环境配置十八:数据驱动(Read CSV File)
- bzoj 1251 序列终结者
- QTcpSocket 及 TCP粘包分析
- Windows多媒体定时器(精确到1ms)
- 图 基本概念和性质
- JSP三种页面跳转方式的比较
- C#中使用MATLAB
- 网络寻路(dfs或者枚举)
- linux自旋锁——读写锁
- nginx.conf配置示例讲解