ZOJ 2112 Dynamic Rankings

这里是题目地址

 

其实就是带修改的区间第K大。

写了一下BIT套主席树,内存飞起,似乎需要特别的优化技巧 = = 所以还是写了一下线段树套平衡树,跑了1s左右。

其实线段树套平衡树就是归并树的自然扩展而已。

归并树是把归并排序的过程建成一颗线段树,每个节点是一个数组,存的是这个节点对应区间的元素的正序:

空间复杂度O( n log n ) 。

每次查询的时候二分答案, 问题转化成询问区间中有多少个数比k小。外层查询和一般的线段树一样,只是在线段树的节点处需要再次二分得到节点区间中比k小的数的个数。这样二分答案有一个log ,线段树中询问也需要一个log ,线段树节点处二分需要一个log ,每次询问的复杂度为O( log^3 n ) 。

 

加入修改操作的时候,只需要把线段树节点的数组改为平衡树实现就好了。这是很自然的,线段树节点维护对应节点的顺序,又要支持修改,显然平衡树符合要求。

平衡树用splay实现了一下跑了1080ms ,然后用Treap实现了一下RE得浑身难受。。。实在是码力不行啊Orz

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std ;
  5 const int N = 50000 +10 ,INF = ~1u>>1;
  6 int M ,num[N] ;
  7 struct node{
  8     node *ch[2] ,*p ;
  9     int size ,val ;
 10     bool d() ;
 11     void setc( node * ,bool ) ,rol() ,pushup() ;
 12 }pool[N*19] ,*cur ,NU ,*null = &NU ;
 13 bool node::d(){
 14     return p->ch[1] == this ;
 15 }
 16 void node::setc( node *c ,bool d ){
 17     ch[d] = c ,c->p = this ;
 18 }
 19 void node::rol(){
 20     node *s = p ;
 21     int dd = d() ;
 22     s->p->setc( this ,p->d() ) ;
 23     s->setc( ch[!dd] ,dd ) ;
 24     setc( s ,!dd ) ;
 25     s->pushup() ;
 26 }
 27 void node::pushup(){
 28     size = ch[0]->size + ch[1]->size + 1 ;
 29 }
 30 struct Splay{
 31     node *root ;
 32     void splay( node * ,node * ) ,insert( node * ) ;
 33     void change( int ,int ) ,find( int ) ,init() ;
 34     node *get( int ) ;
 35     int rank( int ) ;
 36 }tree[N<<2] ;
 37 
 38 node *newnode( int val ){
 39     cur->val = val ;
 40     cur->size = 1 ;
 41     cur->ch[0] = cur->ch[1] = cur->p = null ;
 42     return cur ++ ;
 43 }
 44 void Splay::init(){
 45     root = newnode(-INF) ;
 46 }
 47 void Splay::splay( node *x ,node *p = null ){
 48     while( x->p != p ){
 49         if( x->p->p != p )
 50             x->d() == x->p->d() ? x->p->rol() : x->rol() ;
 51         x->rol() ;
 52     }
 53     x->pushup() ;
 54     if( p == null ) root = x ;
 55 }
 56 void Splay::insert( node *x ){
 57     if( root == null ) root = x ,root->p = null ;
 58     else for( node *t = root ;; ){
 59         ++t->size ;
 60         node *&s = t->ch[ x->val > t->val ] ;
 61         if( s == null ){
 62             s = x ,s->p = t ;
 63             splay( x ) ;
 64             break ;
 65         }
 66         t = s ;
 67     }
 68 }
 69 void Splay::find( int x ){
 70     for( node *t = root ;; ){
 71         if( x == t->val ){
 72             splay( t ) ;
 73             return ;
 74         }
 75         t = t->ch[ x > t->val ] ;
 76     }
 77 }
 78 void Splay::change( int x ,int val ){
 79     find( x ) ;
 80     node *p = root ;
 81     node *t = get( root->ch[0]->size ) ;
 82     splay( t ,root ) ;
 83     t->setc( root->ch[1] ,1 ) ;
 84     t->pushup() ,root = t ,t->p = null ;
 85     p->val = val ,p->size = 1 ;
 86     p->ch[0] = p->ch[1] = null ;
 87     insert( p ) ;
 88     return ;
 89 }
 90 node *Splay::get( int s ){
 91     for( node *t = root ;; ){
 92         int k = t->ch[0]->size ;
 93         if( s == k + 1 ) return t ;
 94         if( s > k + 1 ) s -= k + 1 ,t = t->ch[1] ;
 95         else t = t->ch[0] ;
 96     }
 97 }
 98 int Splay::rank( int x ){
 99     int res = 0 ;
100     for( node *t = root ;; ){
101         node *&s = t->ch[ x > t->val ] ;
102         if( t->val < x ) res += t->ch[0]->size + 1 ;
103         if( s == null ){
104             splay(t) ;
105             return res - 1 ;
106         }
107         t = s ;
108     }
109 }
110 void setIt( int p ,int k ,int s = M ,int x = 1 ){
111     tree[x].insert( newnode(k) ) ;
112     if( s == 1 ) return ;
113     if( p <= s/2 ) setIt( p ,k ,s/2 ,x<<1 ) ;
114     else setIt( p - s/2 ,k ,s - s/2 ,x<<1|1 ) ;
115 }
116 void change( int p ,int u ,int v ,int s = M ,int x = 1 ){
117     tree[x].change( u ,v ) ;
118     if( s == 1 ) return ;
119     if( p <= s/2 ) change( p ,u ,v ,s/2 ,x<<1 ) ;
120     else change( p-s/2 ,u ,v ,s-s/2 ,x<<1|1 ) ;
121 }
122 int Q ;
123 void query( int l ,int r ,int ans ,int s = M ,int x = 1 ){
124     if( l <= 1 && r >= s ){
125         Q += tree[x].rank(ans) ;
126         return ;
127     }
128     if( l <= s/2 ) query( l ,r ,ans ,s/2 ,x<<1 ) ;
129     if( r > s/2 ) query( l-s/2 ,r-s/2 ,ans ,s-s/2 ,x<<1|1 ) ;
130 }
131 bool judge( int l ,int r ,int ans ,int kth ){
132     Q = 0 ;
133     query( l ,r ,ans ) ;
134     if( Q <= kth - 1 ) return 1;
135     return 0 ;
136 }
137 void init(){
138     cur = pool ;
139 }
140 void build( int x = 1 ,int s = M ){
141     tree[x].init() ;
142     if( s == 1 ) return ;
143     build( x<<1 ,s/2 ) ;
144     build( x<<1|1 ,s-s/2 ) ;
145 }
146 int main(){
147     int n ,m ,x ,s ,t ,u ;
148     int T ;
149     scanf( "%d" ,&T ) ;
150     while( T -- ){
151         scanf("%d %d" ,&n ,&m ) ;
152         M = n ;
153         init() ;
154         int minn = 0 ,maxn = 0 ;
155         build();
156         for( int i = 1 ;i <= n ;i ++ ){
157             scanf( "%d" ,&x ) ;
158             num[i] = x ;
159             setIt( i ,x ) ;
160             minn = min ( minn ,x ) ;
161             maxn = max ( maxn ,x ) ;
162         }
163         char o[2];
164         while( m -- ){
165             scanf( "%s" ,&o ) ;
166             if( o[0] == 'C' ){
167                 scanf( "%d %d" ,&s ,&t ) ;
168                 minn = min( minn ,t ) ;
169                 maxn = max( maxn ,t ) ;
170                 change( s ,num[s] ,t ) ;
171                 num[s] = t ;
172                 continue ;
173             }
174             scanf( "%d %d %d" ,&s ,&t ,&u ) ;
175             int l = minn ,r = maxn ;
176             while( l < r ){
177                 int mid = ( l + r >> 1 ) + 1 ;
178                 if( judge( s ,t ,mid ,u ) ) l = mid ;
179                 else r = mid - 1 ;
180             }
181             printf( "%d\n" ,l ) ;
182         }
183     }
184 }
CODE

 

转载于:https://www.cnblogs.com/MyWither/p/3563779.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273854.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python3[进阶]8.对象引用、可变性和垃圾回收

文章目录8.1变量不是盒子8.2 标识,相等性和别名8.2.1 在和is之间选择8.2.2 元组的相对不可变性8.3 默认做浅复制&#xff08;拓展&#xff09;为任意对象做深复制和浅复制深拷贝和浅拷贝有什么具体的区别呢&#xff1f;8.4 函数的参数作为引用时8.4.1 不要使用可变类型作为参数…

openfire修改服务器名称方法

1.登陆openfire管理页面&#xff0c;在主页面下方选择编辑属性&#xff0c;修改服务器名称为当前主机名称&#xff0c;点击保存属性&#xff0c;按页面提示重启服务器。 2.重启后&#xff0c;主页的服务器属性下的服务器名称出现一个叹号&#xff0c;鼠标放上去显示Found RSA c…

python (第八章)补充-可迭代对象(补充高阶函数,以及常用的高阶函数)

文章目录可迭代对象迭代器什么是迭代器什么是生成器生成器的作用生成器的注意事项总结&#xff1a;高阶函数什么是高阶函数&#xff1f;map()函数filter()函数reduce()函数参考可迭代对象 我们已经知道&#xff0c;可以直接作用于for循环的数据类型有以下几种&#xff1a; 一类…

网络阅读开篇

网络阅读也符合马太效应&#xff0c;投入的时间越多&#xff0c;获取的有效信息却越来越少&#xff0c;因此做出以下规定&#xff1a; 1、限制网络阅读时间&#xff1b; 2、每次阅读做总结。 本来想的挺简单的&#xff0c;随便搜了一下&#xff0c;居然一部小心拜读了两位大神的…

python (第二章)数据结构

文章目录2.5 对序列使用 和 建立由列表组成的列表2.6序列的增量赋值&#xff08;和&#xff09;关于 的谜题补充&#xff1a;extend()方法和有什么区别呢&#xff1f;2.7 list.sort方法和内置函数sorted(排序)2.8 用bisect来管理已排序的序列2.8.2用bisect.insort插入元素2.9 当…

数据库 CURD测试题【简单】

文章目录1.组合两个表基本信息要求答案2.第二高的薪水基本信息要求答案3.查找重复的电子邮箱基本信息要求答案4.超过经理收入的员工基本信息要求答案&#xff1a;5.超过5名学生的课信息&#xff1a;要求答案6.有趣的电影信息要求答案7.交换工资&#xff08;updeta,条件判断&…

JAVA学习资料整理

今天偶然间发现之前一个群里发过的一篇关于JAVA学习资料的东西。本着服务大众的精神&#xff0c;搬来了博客园&#xff1a; 《JAVA编程思想》第四版&#xff08;英文原版&#xff09;下载地址&#xff1a;http://115.com/file/e7fzi0fm《JAVA开发实战经典》下载地址&#xff1a…

mysql快速了解

文章目录数据库了解&#xff1a;快速操作&#xff1a;安装mysql启动,关闭,重启mysql服务连接mysql的root用户创建数据库删除数据库选择数据库mysql 数据类型MySQL 创建数据表MySQL 删除数据表MySQL 插入数据MySQL 查询数据MySQL WHERE 子句BINARY 关键字MySQL UPDATE 更新批量更…

javascript编程风格(粗略笔记)

1、空格 紧凑型&#xff1a;    project.MyClass function(arg1, arg2){  松散型&#xff1a;    for( i 0; i < length; i ){ 2、代码行长度  最多80个字符 3、命名: 采用驼峰式方法命名(开始的第一个单词小写&#xff0c;之后的所有单词首字母大写)  var …

数据结构 面试题

文章目录1.数组1.1 寻找数组中第二小的元素1.2 找到数组中第一个不重复出现的整数1.3合并两个有序数组1.4 重新排列数组中的正值和负值2.栈2.1 前缀表达式&#xff0c;中缀表达式&#xff0c;后缀表达式2.1.1 中缀表达式转化为后缀表达式2.1.2 中缀表达式转化为前缀表达式2.2使…

WPF之无法触发KeyDown或者KeyUp键盘事件

有时候我们可能在Panel(StackPanel、Canvas、Grid)上或者是在一些默认不支持Focus的控件上添加了KeyDown或者KeyUp&#xff0c;可是残酷的现实告诉我们&#xff0c;这是无法触发的&#xff0c;怎么办呢&#xff0c;很简单&#xff0c;只需一句代码。 private void MouseLeftBut…

宣布在日本地区正式发布 Windows Azure

&#xfeff;&#xfeff;昨天&#xff0c;我与 Microsoft 日本的集团副总裁 Yasuyuki Higuchi 一同站在台上&#xff0c;宣布在两个新地区正式发布 Windows Azure&#xff1a;日本东部和日本西部。能够亲自见证 Microsoft 对日本市场的持续承诺&#xff0c;对我来说是莫大的荣…

运行cmd状态下MySQL导入导出.sql文件

MySQL导入导出.sql文件步骤如下&#xff1a; 一.MySQL的命令行模式的设置&#xff1a; 桌面->我的电脑->属性->环境变量->新建-> PATH“&#xff1b;path\mysql\bin;”其中path为MySQL的安装路径。 二.简单的介绍一下命令行进入MySQL的方法&#xff1a; 1.C:\&g…

python中的collections

文章目录deque(双向列表)defaultdict(为不存在的key设置默认值)OrderedDictOrderedDict可以实现一个FIFO&#xff08;先进先出&#xff09;的dict&#xff0c;Counter参考collections是Python内建的一个集合模块&#xff0c;提供了许多有用的集合类。deque(双向列表) 使用list…

mysql 面试点

文章目录mysql 运算符1.mysql运算符中的 !和Not的区别&#xff1f;CRUD1.条件判断的用法2. not exits 和not in 的区别3. case when语句mysql函数1.to_days()连接1.什么时候选择右连接&#xff0c;什么时候选择左连接&#xff1f;mysql 运算符 1.mysql运算符中的 !和Not的区别…

[Windows Phone] 实作不同的地图显示模式

[Windows Phone] 实作不同的地图显示模式 原文:[Windows Phone] 实作不同的地图显示模式前言 本文章主要示范如何让地图有不同的模式产生&#xff0c;例如平面图、地形图、鸟瞰图、鸟瞰图含街道等。 这部分主要是调整 Map.CartographicMode 属性&#xff0c;其中 MapCartograph…

数据库 CURD测试题【中等】

文章目录1.换座位&#xff08;交换相邻的id&#xff09;基本信息要求答案[case when]2.分数排名(分组&#xff0c;排序)基本信息要求答案3.连续出现的数字(连接)信息要求答案4.第N高的薪水(函数)信息要求答案5.各个部门工资最高的员工(分组&#xff0c;连接)信息要求答案6.统计…

[STemWin教程入门篇]第一期:emWin介绍

特别说明&#xff1a;原创教程&#xff0c;未经许可禁止转载&#xff0c;教程采用回复可见的形式&#xff0c;谢谢大家的支持。 armfly-x2,x3,v2,v3,v5开发板裸机和带系统的emWin工程已经全部建立&#xff0c;链接如下&#xff1a; http://bbs.armfly.com/read.php?tid1830 SE…

python 栈【测试题】

文章目录1.删除最外层的括号信息要求答案2.棒球比赛信息示例答案3. 用栈实现队列要求说明:答案4.用队列模拟栈描述注意答案5.下一个更大的元素&#xff08;未解&#xff09;信息&#xff1a;示例&#xff1a;注意:答案&#xff1a;6.删除字符串中的所有相邻重复项信息示例&…