人生第一发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. 关于strlen

    strlen的实现是通过4个字节4个字节进行枚举,然后通过位运算来判断这4个字节中是否有一个字节含有0,这样的话,效率就提高了4倍. 这个效率提高是假设a&b&c&d与a&am ...

  2. Android消息机制之实现两个不同线程之间相互传递数据相互调用

    目的:实现两个不同线程之间相互传递数据相互调用方法. 线程一中定义mainHandler 并定义一个方法mainDecode 线程二中定义twoHandler 并定义一个方法twoEncode 实现当 ...

  3. Android 防止按钮连续点击的方法(Button,ImageButton等)

    防止按钮连续点击  其实实现很简单 共通方法 public class Utils { private static long lastClickTime; public static boolean ...

  4. 开发ProxyServer的时候如何在一台PC上调试

    为了测试在真实的网络环境下你的ProxyServer性能如何,而你手头又只有一台电脑,怎么办? 打开你的ProxyServer(我用java写的,因此ProxyServer的进程是javaw.exe) ...

  5. C语言 将整数写入内存指定的连续字节单元中

    将整数数组写入0x40003000开始的连续10个字节内存单元中,注意unsigned char *指向一个字节,而int *指向1个字(4个字),但是可以把字中存储的整数放入字节单元中,只要不超过表 ...

  6. HDU 4607 Park Visit 两次DFS求树直径

    两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R:   ans = ...

  7. dojo 十二 rest

    从今年8月份开始一直在做以HTML5+CSS3+Dojo实现前端设计,以REST风格实现后台数据请求的项目研发.实践出真知,现在对研发中用到的技术和遇到的问题做一个总结. 后台服务没有采用那些主流的框 ...

  8. 10.cadence.自定义焊盘的创建[原创]

    一.自定义图形焊盘 1.设置环境(面板大小,格点) --- ------ 圆形 Shape > Circular ---- 两个DRC错误,证明图形重合了, 将图形复合一下: --- 椭圆类焊盘 ...

  9. guidelines for contributing Hearthstone-Deck-Tracker

    https://github.com/Epix37/Hearthstone-Deck-Tracker/blob/master/CONTRIBUTING.md Coding style Always u ...

  10. Restrict each user to a single session in window server 2008 R2 or 2012

    Restrict each user to a single session in window server 2008 R2 or 2012 2014-10-31 In window server ...