人生第一发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)的更多相关文章

  1. [bzoj1251]序列终结者——splay

    题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...

  2. [BZOJ1251]序列终结者

    [BZOJ1251]序列终结者 试题描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题 ...

  3. 【BZOJ1251】序列终结者 Splay

    一道模板题,一直没发现自己的快速读入读不了负数,我竟然能活到现在真是万幸. #include <iostream> #include <cstdio> #define inf ...

  4. bzoj1251 序列终结者(Splay Tree+懒惰标记)

    Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...

  5. BZOJ1251 序列终结者(Splay平衡树)(占位)

    网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量…… ...

  6. [bzoj1251]序列终结者_splay

    序列终结者 bzoj-1251 题目大意:给定一个长度为n的正整数序列,支持区间加,区间反转,查询区间最大值.所有元素开始都是0. 注释:$1\le n\le 5\cdot 10^4$,操作个数不多于 ...

  7. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

  8. CODEVS 4655 序列终结者-splay(区间更新、区间翻转、区间最值)

    4655 序列终结者  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解       题目描述 Description 网上有许多题,就是给定一个序列,要 ...

  9. bzoj 1251序列终结者 splay 区间翻转,最值,区间更新

    序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 4594  Solved: 1939[Submit][Status][Discuss] De ...

随机推荐

  1. Java日期转换SimpleDateFormat格式大全(转)

    24小时制时间显示: public class Datetime { public static void main(String args[]){ java.util.Date current=ne ...

  2. python操作json

    概念 序列化(Serialization):将对象的状态信息转换为可以存储或可以通过网络传输的过程,传输的格式可以是JSON.XML等.反序列化就是从存储区域(JSON,XML)读取反序列化对象的状态 ...

  3. 14_把文件存放在SDCard

    权限添加 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> /** ...

  4. URL重写的优缺点分析

    如何增强您网站地址的可读性.如何让搜索引擎快速收录到您的站点,这就需要优化您的Url,即Url的重写技术,大家熟悉的可能有很多服务器都提供Url重写技术,以前我们用的最多的就是Apache,Jboss ...

  5. ILog JRules 标识符 X 未定义

    在定义枚举值时,属性“转译”(“translation”),定义字符串时需要双引号,相当于value值. 其属性值如果只有字符串,而没有双引号,在编译或者执行时就会报“标识符X未定义”的错误信息.

  6. 二叉搜索树的两种实现(数组模拟,STL)

    书上实现: 二叉搜索数的特点:高效实现 插入一个数值,查询是否包含某个数值,删除某一个数值. 所有的节点都满足左子树上的所有节点都比自己的小,而右子树上的所有节点都比自己大的特点. 查询:如果当前数值 ...

  7. 【Android】MTK Android 编译命令

    命令格式:./maketek [option] [project] [action] [modules] Option: -t ,-tee :输出log信息到当前终端 -o , -opt=-- : 编 ...

  8. 《OD学hadoop》mac下使用VMware Fusion安装centos

    一. NAT模式网络访问 (1)在linux中输入命令ifconfig查看网络信息 (2)在mac中输入命令ifconfig查看网络信息 lo0: flags=<UP,LOOPBACK,RUNN ...

  9. HTML的列表标签

    一.上下层列表标签:<dl>..</dl>: 上层dt 下层dd:封装的内容会被自动缩进的效果 <dl> <dt>运动户外</dt> < ...

  10. HDU 1025 (LIS+二分) Constructing Roads In JGShining's Kingdom

    这是最大上升子序列的变形,可并没有LIS那么简单. 需要用到二分查找来优化. 看了别人的代码,给人一种虽不明但觉厉的赶脚 直接复制粘贴了,嘿嘿 原文链接: http://blog.csdn.net/i ...