bzoj1251 序列终结者(Splay Tree+懒惰标记)
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
1 1 3 2
1 2 4 -1
2 1 3
3 2 4
Sample Output
【数据范围】
N<=50000,M<=100000。
【思路】
Splay
Tree+懒惰标记。
用Splay Tree维护序列,添加flip,maxv,addv作为结点信息,其中flip与addv是懒惰标记,需要在Splay中调用pushdown下传标记。对于每次操作,将区间lr分裂出来后执行即可。
【代码】
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; const int maxn = +;
const int INF = 1e9;
inline int read() {
char c=getchar();
while(!isdigit(c)) c=getchar();
int x=;
while(isdigit(c)) {
x=x*+c-'';
c=getchar();
}
return x;
} struct Node {
Node* ch[];
int v,s,flip,addv,maxv;
int cmp(int k) const {
int d=k - ch[]->s;
if(d==) return -;
return d<=? :;
}
void pushdown() {
if(addv) {
v+=addv;
ch[]->addv+=addv,ch[]->addv+=addv;
addv=;
}
if(flip) {
flip=; swap(ch[],ch[]); ch[]->flip^=,ch[]->flip^=;
}
}
void maintain() {
s=ch[]->s+ch[]->s+;
maxv=max(ch[]->v,ch[]->v),maxv=max(maxv,v);
}
};
Node* null=new Node();
void rotate(Node* &o,int d) {
Node* k=o->ch[d^]; o->ch[d^]=k->ch[d],k->ch[d]=o;
o->maintain(),k->maintain(); o=k;
}
void splay(Node* &o,int k) { //splay 的同时pushdown 下传标记
o->pushdown();
int d=o->cmp(k);
if(d==) k-=o->ch[]->s+;
if(d!=-) {
Node* p=o->ch[d];
p->pushdown();
int d2=p->cmp(k);
int k2=d2==? k-p->ch[]->s-:k;
if(d2!=-) {
splay(p->ch[d2],k2);
if(d==d2) rotate(o,d^); else rotate(o->ch[d],d);
}
rotate(o,d^);
}
}
Node* merge(Node* left,Node* right) {
splay(left,left->s);
left->ch[]=right,left->maintain();
return left;
}
void split(Node* o,int k,Node* &left,Node* &right) {
splay(o,k);
left=o,right=left->ch[],left->ch[]=null,left->maintain();
}
struct SplaySeq {
int n;
Node *root,seq[maxn];
Node* build(int sz) {
if(!sz) return null;
Node* l=build(sz/);
Node* o=&seq[++n];
o->v=,o->maxv=-INF;
o->ch[]=l,o->ch[]=build(sz-sz/-);
o->flip=o->s=;
o->maintain();
return o;
}
void init(int sz) {
n=null->s=null->addv=;
null->v=null->maxv=-INF;
root=build(sz);
}
}ss; int n,m;
int main() {
n=read(),m=read();
ss.init(n+);
int k,l,r,v;
Node *left,*right,*mid;
for(int i=;i<m;i++) {
k=read(),l=read(),r=read();
split(ss.root,l,left,right),split(right,r-l+,mid,right);
switch(k) {
case :
v=read(); mid->addv+=v;
break;
case :
mid->flip^=;
break;
case :
printf("%d\n",mid->maxv);
break;
}
ss.root = merge(merge(left,mid),right);
}
return ;
}
bzoj1251 序列终结者(Splay Tree+懒惰标记)的更多相关文章
- [bzoj1251]序列终结者——splay
题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...
- bzoj1251 序列终结者(splay)
人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain 9k代码不忍直视 #define NDEBUG #include<cstdio> #includ ...
- [BZOJ1251]序列终结者
[BZOJ1251]序列终结者 试题描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题 ...
- 【BZOJ1251】序列终结者 Splay
一道模板题,一直没发现自己的快速读入读不了负数,我竟然能活到现在真是万幸. #include <iostream> #include <cstdio> #define inf ...
- BZOJ1251 序列终结者(Splay平衡树)(占位)
网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量…… ...
- BZOJ 1251: 序列终结者 [splay]
1251: 序列终结者 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3778 Solved: 1583[Submit][Status][Discu ...
- CODEVS 4655 序列终结者-splay(区间更新、区间翻转、区间最值)
4655 序列终结者 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Description 网上有许多题,就是给定一个序列,要 ...
- [bzoj1251]序列终结者_splay
序列终结者 bzoj-1251 题目大意:给定一个长度为n的正整数序列,支持区间加,区间反转,查询区间最大值.所有元素开始都是0. 注释:$1\le n\le 5\cdot 10^4$,操作个数不多于 ...
- BZOJ1251序列终结者——非旋转treap
题目描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...
随机推荐
- PTHREAD_MUTEX_INITIALIZER问题
PTHREAD_MUTEX_INITIALIZER 与 expected expression before ‘{’ token 在进行 Posix thread 编程时,出现以下编译错误:err ...
- Android开发手记(26) Java多线程的实现
随着多核CPU的发展,多线程编程显得越来越重要,本文将对Java中的多线程编程进行一些简单的探讨. 1.继承Thread类 Java中,线程运行的基本单位是Thread,所以,我们可以通过继承Thre ...
- HashMap HashTable HashSet
原文转载自 http://blog.csdn.net/wl_ldy/article/details/5941770 HashMap是新框架中用来代替HashTable的类 也就是说建议使用HashMa ...
- ASIHttpRequest网络请求第三方类库使用方法详解
一. 第一步首先你要从网络上下载ASIHttpRequestlib, 下载以后解压,增加到你的工程里面, 这个时间检查工程内部是否已经导入成功,文件结构如下: ASIHTTPRequestConfig ...
- js判断是否在iframe中
1.方式一 if (self.frameElement && self.frameElement.tagName == "IFRAME") { alert('在if ...
- 深入理解ReentrantLock
在Java中通常实现锁有两种方式,一种是synchronized关键字,另一种是Lock.二者其实并没有什么必然联系,但是各有各的特点,在使用中可以进行取舍的使用.首先我们先对比下两者. 实现: 首先 ...
- 24种设计模式--多例模式【Multition Pattern】
这种情况有没有?有!大点声,有没有?有,是,确实有,就出现在明朝,那三国期间的算不算,不算,各自称帝,各有各的地盘,国号不同.大家还 记得那首诗<石灰吟>吗?作者是谁?于谦,他是被谁杀死的 ...
- ubuntu 升级命令
apt-get update && apt-get dist-upgrade
- linux之uniq
Linux命令uniq的作用是过滤重复部分显示文件内容,这个命令读取输入文件,并比较相邻的行.在正常情况下,第二个及以后更多个重复行将被删去,行 比较是根据所用字符集的排序序列进行的.该命令加工后的结 ...
- 菜鸟必备教程,ajax与xml交互传输数据。
今天,公司让学习ajax,然而我并不会,着急到爆炸,boom~~啥卡拉咔.看着教程一步一步摸索,写出来交互页面,写代码真的好惆怅啊. 额,不说废话,下面是源代码. 首先是ajax的代码,注释真的很重要 ...