bzoj1251 序列终结者(splay)
人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain
9k代码不忍直视
#define NDEBUG
#include<cstdio>
#include<cassert>
#include<climits>
#include<cstdlib>
#include<algorithm>
#ifndef NDEBUG
#define int_out(_a_) printf(#_a_"=%d\n",_a_) ;
#else
#define int_out(_a_) {}
#endif
class splay_tree {
private :
struct node ;
node * link_node ( node * const father , node * const child , const int d ) ;
mutable node * root ;
static node * const nil ;
node * kth ( const int k ) ;
node * max () ;
public :
splay_tree () ;
splay_tree ( int k , const int value ) ;
~splay_tree () ;
void add ( const int L , const int R , const int value ) ;
void reverse ( const int L , const int R ) ;
int max ( const int L , const int R ) ;
void split ( const int k , splay_tree & output ) ;
void merge ( splay_tree & input ) ;
void clear () ;
void distory () ;
} ; struct splay_tree :: node {
int value ;
int add_value , reverse , max_value ;
int size ;
node * ch [ ] ;
node * father ;
node ( const int value = INT_MIN / , const int size = ) ;
~node () ;
node * splay () ;
void rotate () ;
void push_down () ;
void maintain () ;
#ifndef NDEBUG
void dfs() ;
void _dfs( const int , const int ) ;
#endif
} ; #ifndef NDEBUG
void splay_tree :: node :: dfs () {
if ( this != nil ) this -> _dfs ( , ) ; putchar ( '\n' ) ;
} void splay_tree :: node :: _dfs ( const int addv , const int re ) {
if ( ch [ re ] != nil ) ch [ re ] -> _dfs ( addv + add_value , re ^ ( reverse ) ) ;
printf ( "%d " , value + add_value + addv ) ;
if ( ch [ re ^ ] != nil ) ch [ re ^ ] -> _dfs ( addv + add_value , re ^ reverse ) ;
}
#endif //nil声明
splay_tree :: node * const splay_tree :: nil = new node ( INT_MIN , ) ; //node构造及析构函数
splay_tree :: node :: node ( const int value , const int size ) :
value ( value ) , add_value ( ) , reverse ( ) , max_value ( value ) , size ( size ) , father ( nil ) { ch [ ] = ch [ ] = nil ; } splay_tree :: node :: ~node () {
assert ( this != nil ) ;
if ( ch [ ] != nil ) delete ch [ ] ;
if ( ch [ ] != nil ) delete ch [ ] ;
} //提供连接两个点的简单操作
//我们假设两个参数标记已被清空
inline splay_tree :: node * splay_tree :: link_node ( node * const father , node * const child , const int d ) {
father -> ch [ d ] = child ;
child -> father = father ;
return father ;
} //splay_tree构造及析构函数
splay_tree :: splay_tree () : root ( nil ) {} ; splay_tree :: splay_tree ( int k , const int value ) : root ( nil ) {
while ( k -- ) {
node * const np = new node ( value ) ;
root = link_node ( np , root , ) ;
np -> maintain () ;
}
} splay_tree :: ~splay_tree () {
if ( root != nil ) delete root ;
} //下面三个函数是要支持的三种操作
void splay_tree :: add ( const int L , const int R , const int value ) {
splay_tree mid , right ;
split ( R - , right ) ;
split ( L - , mid ) ;
#ifndef NDEBUG
printf ( "add split\n" ) ;
#endif
mid . root -> add_value += value ;
mid . root -> maintain () ;
#ifndef NDEBUG
int_out(root->size);
printf ( "size of mid = %d\n" , mid . root -> size ) ;
int_out(right.root->size);
#endif
merge ( mid ) ;
merge ( right ) ;
int_out(root->size);
#ifndef NDEBUG
root -> dfs () ;
#endif
} void splay_tree :: reverse ( const int L , const int R ) {
splay_tree mid , right ;
split ( R - , right ) ;
split ( L - , mid ) ;
mid . root -> reverse ^= ;
merge ( mid ) ;
merge ( right ) ;
int_out (root->size) ;
} int splay_tree :: max ( const int L , const int R ) {
splay_tree mid , right ;
split ( R - , right ) ;
split ( L - , mid ) ;
const int ans = mid . root -> max_value ;
#ifndef NDEBUG
int_out(root->size);
root -> dfs () ;
printf ( "size of mid = %d\n" , mid . root -> size ) ;
mid . root -> dfs () ;
int_out(right.root->size);
right . root -> dfs () ;
#endif
merge ( mid ) ;
merge ( right ) ;
int_out(root->size);
#ifndef NDEBUG
root -> dfs () ;
#endif
return ans ;
} //为splay_tree提供split和merge操作
void splay_tree :: split ( const int k , splay_tree & output ) {
int_out(k);
output . distory () ;
if ( k > this -> root -> size ) return ;
if ( k == ) {
output . root = root ;
clear () ;
#ifndef NDEBUG
printf ( "now the tree is empty\n" ) ;
#endif
} else {
kth ( k ) ;
output . root = root -> ch [ ] ;
output . root -> father = nil ;
root -> ch [ ] = nil ;
root -> maintain () ;
}
} void splay_tree :: merge ( splay_tree & input ) {
if ( root == nil ) {
root = input . root ;
} else {
max () ;
link_node ( root , input . root , ) ;
root -> maintain () ;
}
input . clear () ;
} //clear & distroy void splay_tree :: clear () {
root = nil ;
} void splay_tree :: distory () {
if ( root != nil ) root -> ~node () ;
root = nil ;
} //kth & max
splay_tree :: node * splay_tree :: kth ( int k ) {
#ifndef NDEBUG
printf ( "kth begin\n" ) ;
#endif
node * o = root ;
while ( o -> push_down () , k != o -> ch [ ] -> size + ) {
assert ( o != nil ) ;
const int d = k > o -> ch [ ] -> size + ;
if ( d != ) k -= o -> ch [ ] -> size + ;
o = o -> ch [ d ] ;
}
( root = o ) -> splay () ;
return root ;
} splay_tree :: node * splay_tree :: max () {
node * o = root ;
assert ( o != nil ) ;
while ( o -> push_down () , o -> ch [ ] != nil ) o = o -> ch [ ] ;
( root = o ) -> splay () ;
return root ;
} //rotate /*
void splay_tree :: node :: rotate () {
assert ( this != nil ) ;
node * const father = this -> father ;
father -> push_down () ;
this -> push_down () ;
const int d = father -> ch [ 1 ] == this ;
this -> father = this -> father -> father ;
if ( this -> father -> father != nil ) {
const int d2 = this -> father -> father -> ch [ 1 ] == father ;
father -> father -> ch [ d2 ] = this ;
}
father -> ch [ d ] = this -> ch [ d ^ 1 ] ;
father -> ch [ d ] -> father = father ;
this -> ch [ d ^ 1 ] = father ;
father -> father = this ;
father -> maintain () ;
this -> maintain () ;
}*/ void splay_tree :: node :: rotate () {
assert ( this != nil ) ;
node * const father = this -> father ;
assert ( father != nil ) ; father -> push_down () ;
this -> push_down () ; const int d = father -> ch [ ] == this ;
if ( this -> father -> father != nil ) {
const int d2 = this -> father -> father -> ch [ ] == this -> father ;
( this -> father = father -> father ) -> ch [ d2 ] = this ;
} else this -> father = nil ;
( father -> ch [ d ] = this -> ch [ d ^ ] ) -> father = father ;
( this -> ch [ d ^ ] = father ) -> father = this ; father -> maintain () ;
this -> maintain () ;
} splay_tree :: node * splay_tree :: node :: splay () {
assert ( this != nil ) ;
while ( this -> father != nil && this -> father -> father != nil ) {
this -> father -> father -> push_down () ;
this -> father -> push_down () ;
this -> push_down () ;
const int d1 = this -> father -> father -> ch [ ] == this -> father ;
const int d2 = this -> father -> ch [ ] == this ;
if ( d1 == d2 ) this -> father -> rotate () ;
else this -> rotate () ;
this -> rotate () ;
}
if ( this -> father != nil ) this -> rotate () ;
return this ;
} void splay_tree :: node :: push_down () {
assert ( this != nil ) ;
if ( this -> reverse ) {
std :: swap ( this -> ch [ ] , this -> ch [ ] ) ;
if ( ch [ ] != nil ) this -> ch [ ] -> reverse ^= ;
if ( ch [ ] != nil ) this -> ch [ ] -> reverse ^= ;
reverse = ;
}
if ( this -> add_value != ) {
this -> value += this -> add_value ;
if ( ch [ ] != nil ) this -> ch [ ] -> add_value += this -> add_value ;
if ( ch [ ] != nil ) this -> ch [ ] -> add_value += this -> add_value ;
add_value = ;
}
if ( ch [ ] != nil ) ch [ ] -> maintain () ;
if ( ch [ ] != nil ) ch [ ] -> maintain () ;
} void splay_tree :: node :: maintain () {
assert ( this != nil ) ;
this -> max_value = std :: max ( value , std :: max ( ch [ ] -> max_value , ch [ ] -> max_value ) ) + add_value ;
this -> size = this -> ch [ ] -> size + + this -> ch [ ] -> size ;
} int main () {
int N , M ;
scanf ( "%d%d" , & N , & M ) ;
splay_tree a ( N , ) ;
while ( M -- ) {
int opt , l , r , v ;
scanf ( "%d%d%d" , & opt , & l , & r ) ;
switch ( opt ) {
case :
scanf ( "%d" , & v ) ;
a . add ( l , r + , v ) ;
break ;
case :
a . reverse ( l , r + ) ;
break ;
case :
printf ( "%d\n" , a . max ( l , r + ) ) ;
break ;
}
}
return ;
}
bzoj1251 序列终结者(splay)的更多相关文章
- [bzoj1251]序列终结者——splay
题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...
- [BZOJ1251]序列终结者
[BZOJ1251]序列终结者 试题描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题 ...
- 【BZOJ1251】序列终结者 Splay
一道模板题,一直没发现自己的快速读入读不了负数,我竟然能活到现在真是万幸. #include <iostream> #include <cstdio> #define inf ...
- bzoj1251 序列终结者(Splay Tree+懒惰标记)
Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...
- BZOJ1251 序列终结者(Splay平衡树)(占位)
网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量…… ...
- [bzoj1251]序列终结者_splay
序列终结者 bzoj-1251 题目大意:给定一个长度为n的正整数序列,支持区间加,区间反转,查询区间最大值.所有元素开始都是0. 注释:$1\le n\le 5\cdot 10^4$,操作个数不多于 ...
- 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 网上有许多题,就是给定一个序列,要 ...
- bzoj 1251序列终结者 splay 区间翻转,最值,区间更新
序列终结者 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4594 Solved: 1939[Submit][Status][Discuss] De ...
随机推荐
- Drozer安装
(1)JDK安装 http://www.cnblogs.com/linbc/p/4319509.html http://blog.csdn.net/qq_31988895/article/detail ...
- oracle11g手工建库步骤
平台:Linux AS release 5,Oracle11.1.0.7db_name = SBDB 1. 设置环境变量export ORACLE_BASE=/opt/oracleexport ORA ...
- linux下jdk安装 failed /usr/local/jdk1.6.0_10/jre/lib/i386/client/libjvm.so
今天在fedora core 4下面安装jdk1.6后,运行java -version,没有出现相关的版本信息,而是出现了以下错误: dl failure on line 685Error: fail ...
- JavaScript一些关键概念
垃圾回收:http://www.cnblogs.com/dolphinX/p/3348468.html 引用计数和标记清除 作用链和闭包:http://www.cnblogs.com/dolphinX ...
- Android: 启动init.rc 中service的权限问题【转】
转自:http://www.linuxidc.com/Linux/2011-04/35014.htm 通过property_set("ctl.start", service_xx) ...
- python lambda函数详细解析(面试经常遇到)
1 作用:通常是用来在python中创建匿名函数的 2 格式: lambda 参数[,参数] : 表达式 3 注意: (1)lambda定义的是单行函数, 如果需要复杂的函数,应该定义普通函数 (2) ...
- umount移动硬盘遇到device is busy问题
#umount /mnt/fourtumount: /mnt/fourt: device is busy. (In some cases useful info about proce ...
- 《OD学hadoop》Hadoop前置
一.Hadoop 前置课程 1. Linux系统,基本命令 2. Java语言,JavaSE相关知识 3. MySQL基本的DML和DDL SQL on Hadoop
- RabbitMQ用户角色及权限控制
RabbitMQ的用户角色分类:none.management.policymaker.monitoring.administrator RabbitMQ各类角色描述:none不能访问 managem ...
- Replication in Kafka
Replication简介 Kafka中的Replication功能是为了给每个partition提供备份,当某个Broker挂掉时可以迅速实现故障切换(failover).我们可以在创建或修改top ...