BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )

时间:2022-03-26 18:36:06

BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )

这道题做法应该很多吧....

我用了线段树套treap....

--------------------------------------------------------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<iostream>
 
#define rep( i , n ) for( int i = 0 ; i < n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
#define M( l , r ) ( ( ( l ) + ( r ) ) >> 1 )
 
using namespace std;
 
const int maxn = 50000 + 5;
const int maxnode = 1500000;
const int inf = 1e9;
const unsigned int A = 654321 , B = 54321;
 
int seq[ maxn ] , mn , mx , n;
unsigned int P = 820;
 
// treap node
struct Node {
Node* ch[ 2 ];
int s , v;
unsigned int r;
Node() : s( 0 ) { }
inline void upd() {
s = ch[ 0 ] -> s + ch[ 1 ] -> s + 1;
}
} pool[ maxnode ] , *pt = pool , *null = pt++;
 
Node* newNode( int v = 0 ) {
pt -> v = v;
( P *= A ) += B;
pt -> r = P;
pt -> s = 1;
pt -> ch[ 0 ] = pt -> ch[ 1 ] = null;
return pt++;
}
 
struct treap {
Node* root;
treap() {
root = null;
}
void rot( Node* &t , int d ) {
Node* k = t -> ch[ d ^ 1 ];
t -> ch[ d ^ 1 ] = k -> ch[ d ];
k -> ch[ d ] = t;
t -> upd() , k -> upd();
t = k;
}
void ins( Node* &t , int v ) {
if( t == null )
t = newNode( v );
else {
int d = v > t -> v;
ins( t -> ch[ d ] , v );
if( t -> ch[ d ] -> r > t -> r )
   rot( t , d ^ 1 );
}
t -> upd();
}
void del( Node* &t , int v ) {
int d = t -> v == v ? -1 : ( t -> v < v );
if( d == -1 ) {
if( t -> ch[ 0 ] != null & t -> ch[ 1 ] != null ) {
int h = t -> ch[ 0 ] -> r > t -> ch[ 1 ] -> r;
rot( t , h ) , del( t -> ch[ h ] , v );
} else
   t = t -> ch[ 0 ] == null ? t -> ch[ 1 ] : t -> ch[ 0 ];
} else 
   del( t -> ch[ d ] , v );
if( t != null ) t -> upd();
}
int select( int k ) {
for( Node* t = root ; ; ) {
int s = t -> ch[ 0 ] -> s + 1;
if( k == s + 1 ) return t -> v;
if( k < s )
   t = t -> ch[ 0 ];
else
   k -= s + 1 , t = t -> ch[ 1 ];
}
}
int rank( int v ) {
int ans = 0;
for( Node* t = root ; t != null ; ) {
if( t -> v < v )
   ans += t -> ch[ 0 ] -> s + 1 , t = t -> ch[ 1 ];
else 
   t = t -> ch[ 0 ];
}
return ans;
}
int pred( int v ) {
int ans = -inf;
for( Node* t = root ; t != null ; ) {
if( t -> v < v )
   ans = max( ans , t -> v ) , t = t -> ch[ 1 ];
else
   t = t -> ch[ 0 ];
}
return ans;
}
int succ( int v ) {
int ans = inf;
for( Node* t = root ; t != null ; ) {
if( t -> v > v )
   ans = min( t -> v , ans ) , t = t -> ch[ 0 ];
else 
   t = t -> ch[ 1 ];
}
return ans;
}
} TREAP[ maxn << 1 ] , *pit = TREAP;
 
// segment tree node
struct node {
node *l , *r;
treap* x;
} mem[ maxn << 1 ] , *pT = mem , *Rt;
 
int L , R , v;
 
void build( node* t , int l , int r ) {
t -> x = pit++;
for( int i = l ; i <= r ; i++ )
   t -> x -> ins( t -> x -> root , seq[ i ] );
if( r > l ) {
int m = M( l , r );
build( t -> l = pT++ , l , m );
build( t -> r = pT++ , m + 1 , r );
}
}
 
void change( node* t , int l , int r ) {
if( r < L || l > L ) return;
t -> x -> del( t -> x -> root , seq[ L ] );
t -> x -> ins( t -> x -> root , v );
if( l == r ) return;
int m = M( l , r );
L <= m ? change( t -> l , l , m ) : change( t -> r , m + 1 , r );
}
 
int rank( node* t , int l , int r ) {
if( L <= l && r <= R ) 
   return t -> x -> rank( v );
int m = M( l , r );
return ( L <= m ? rank( t -> l , l , m ) : 0 ) +
      ( m < R ? rank( t -> r , m + 1 , r ) : 0 );
}
 
int pred( node* t , int l , int r ) {
if( L <= l && r <= R ) 
   return t -> x -> pred( v );
int m = M( l , r );
if( R <= m ) return pred( t -> l , l , m );
else if( L > m ) return pred( t -> r , m + 1 , r );
else return max( pred( t -> l , l , m ) , pred( t -> r , m + 1 , r ) );
}
 
int succ( node* t , int l , int r ) {
if( L <= l && r <= R ) 
   return t -> x -> succ( v );
int m = M( l , r );
if( R <= m ) return succ( t -> l , l , m );
else if( L > m ) return succ( t -> r , m + 1 , r );
else return min( succ( t -> l , l , m ) , succ( t -> r , m + 1 , r ) );
}
 
int select( int k ) {
int l = mn , r = mx , ans;
while( l <= r ) {
v = M( l , r );
int h = rank( Rt , 1 , n );
if( rank( Rt , 1 , n ) < k )
   ans = v , l = v + 1;
else
   r = v - 1;
}
return ans;
}
 
inline void read( int &x ) {
x = 0;
int sign = 1;
char c = getchar();
for( ; ! isdigit( c ) ; c = getchar() )
   if( c == '-' ) sign = -1;
for( ; isdigit( c ) ; c = getchar() )
   x = x * 10 + c - '0';
x *= sign;
}
 
int main() {
// freopen( "test.in" , "r" , stdin );
int m;
cin >> n >> m;
Rep( i , n ) {
   read( seq[ i ] );
   mn = i == 1 ? seq[ i ] : min( seq[ i ] , mn );
   mx = i == 1 ? seq[ i ] : max( seq[ i ] , mx );
}
build( Rt = pT++ , 1 , n );
int opt;
while( m-- ) {
read( opt ) , read( L );
switch( opt ) {
case 1 : read( R ); read( v ); printf( "%d\n" , rank( Rt , 1 , n ) + 1 ); break;
case 2 : read( R ); read( v ); printf( "%d\n" , select( v ) ); break;
case 3 : read( v ); change( Rt , 1 , n ); seq[ L ] = v; mn = min( v , mn ); mx = max( mx , v ); break;
case 4 : read( R ); read( v ); printf( "%d\n" , pred( Rt , 1 , n ) ); break;
case 5 : read( R ); read( v ); printf( "%d\n" , succ( Rt , 1 , n ) ); break;
}
}
return 0;
}

--------------------------------------------------------------------------------------------------------------

3196: Tyvj 1730 二逼平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1324  Solved: 562
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)

Input

第一行两个数 n,m 表示长度为n的有序序列和m个操作
第二行有n个数,表示有序序列
下面有m行,opt表示操作标号
若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

Output

对于操作1,2,4,5各输出一行,表示查询结果

Sample Input

9 6
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5

Sample Output

2
4
3
4
9

HINT

1.n和m的数据范围:n,m<=50000

2.序列中每个数的数据范围:[0,1e8]

3.虽然原题没有,但事实上5操作的k可能为负数

Source

BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )的更多相关文章

  1. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1807  Solved: 772[Submit][Stat ...

  2. bzoj 3196&sol; Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  3. BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay

    传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排 ...

  4. bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】

    四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...

  5. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  6. bzoj 3196&colon; Tyvj 1730 二逼平衡树

    #include<cstdio> #include<ctime> #include<cstdlib> #include<iostream> #defin ...

  7. BZOJ 3196 Tyvj 1730 二逼平衡树 树套树 线段树 treap

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 http://hzwer.com/2734.html 线段树套treap,似乎splay也可以 ...

  8. BZOJ - 3196 Tyvj 1730 二逼平衡树 &lpar;线段树套treap&rpar;

    题目链接 区间线段树套treap,空间复杂度$O(nlogn)$,时间复杂度除了查询区间k大是$O(log^3n)$以外都是$O(log^2n)$的. (据说线段树套线段树.树状数组套线段树也能过?) ...

  9. bzoj 3196&sol;tyvj p1730 二逼平衡树

    原题链接:http://www.tyvj.cn/p/1730 树套树... 如下: #include<cstdio> #include<cstdlib> #include&lt ...

随机推荐

  1. Android——什么是3G

    第三代数字通讯技术(3id Generation) 3G与2G的主要区别是:在传输声音和数据的速度上的提升. 1995年问世的第一代模拟制式手机1G只能进行语音通话. 1996年出现的第二代GSM C ...

  2. Allegro学习&lpar;http&colon;&sol;&sol;www&period;asmyword&period;com&sol;forum&period;php&quest;mod&equals;forumdisplay&amp&semi;fid&equals;86&rpar;

    一.资源 1.网站推荐www.eda365.com,里面有很多有用的东西:当然还有官方代理商的网站http://www.pspice.com.cn/: 2.视频教程:有库源电气的视频教程,还有在www ...

  3. Namespaces(命名空间)

    datastore,Blobstore,memcache一起为应用存储数据.这对于在全球范围内分割数据是有用的.比如,一个应用可以为多个公司服务,每个公司可以看到它自己的隔离的应用实例,没有公司可以看 ...

  4. Red and Black

    Red and Black Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  5. 深度学习(一)——CNN算法流程

    深度学习(一)——CNN(卷积神经网络)算法流程 参考:http://dataunion.org/11692.html 0 引言 20世纪60年代,Hubel和Wiesel在研究猫脑皮层中用于局部敏感 ...

  6. springboot学习随笔(四):Springboot整合mybatis(含generator自动生成代码)

    这章我们将通过springboot整合mybatis来操作数据库 以下内容分为两部分,一部分主要介绍generator自动生成代码,生成model.dao层接口.dao接口对应的sql配置文件 第一部 ...

  7. Nginx split&lowbar;client模块

    一般用户AB测试根据比例调用指定的接口  默认编译进nginx Syntax: split_clients string $variable { ... } Default: — Context: h ...

  8. VMware vSphere Client(Vcenter)上传ISO镜像

    .登录Vcenter后选择"数据存储与数据存储集群" .选择存储的路径,右键-选择“浏览数据存储” .点击上传图标,并上传指定的ISO文件

  9. Qt Widgets——抽象旋转框及其继承类

    默认外观分别如下(win7,与上述顺序对应): 可看出,都是由一个可编辑的文本框及右端小箭头组成 QAbstractSpinBox 属性简单解释如下: Properties accelerated : ...

  10. pdf&period;js 使用汇总

    https://www.cnblogs.com/iPing9/p/7154753.htmlhttp://blog.csdn.net/m0_38021128/article/details/708684 ...