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 不要使用可变类型作为参数…

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 当…

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

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

[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.删除字符串中的所有相邻重复项信息示例&…

python进阶(第三章1) 字典

文章目录3.1 泛映射类型什么是可散列的数据类型&#xff08;键的要求&#xff09;字典的构造方法3.2 字典推导(dictcomp)3.3 常见的映射方法用setdefault处理找不到的键3.4 映射的弹性键查询3.4.1 defaultdict:处理找不到的键的一个选择注意&#xff1a;defaultdict与dict实例化…

python基础 list和tuple

文章目录一、list1、len()函数可以获得list元素的个数2、索引从0开始3、末尾追加 append(xx)4、也可以把元素插入到指定的位置&#xff0c;比如索引号为1的位置(insert)5、末尾删除pop() &#xff0c;并且返回该值6、要删除指定位置的元素&#xff0c;用pop(i)方法&#xff0c;…

python基础 dict和set

文章目录dictset4.用集合为列表去重5.集合的增 add,update6.集合的删 discard,remove,pop,clear7 集合运算7.1 子集(<或者issubset()方法)7.2并集(|或者union()方法)7.3 交集(&或者intersection())7.4 差集(-或者difference()方法)7.5 对称集(^或者symmetric_difference…

python进阶(第三章2)字典和集合

文章目录3.8 集合论nee中的元素在haystack中出现的次数&#xff0c;可以在任何可迭代对象上3.8.1集合字面量3.8.2 集合推导3.8.3 集合操作3.9 dict和set的背后3.9.1 一个关于效率的实验3.9.2 字典中的散列表1.散列值和相等性2.散列表算法获取值&#xff1a;添加新的元素更新现有…

Android下实现GPS定位服务

1.申请Google API Key&#xff0c;参考前面文章 2.实现GPS的功能需要使用模拟器进行经纬度的模拟设置&#xff0c;请参考前一篇文章进行设置 3.创建一个Build Target为Google APIs的项目 4.修改Androidmanifest文件&#xff1a; view plain<uses-library android:name"…

DEDECMS全版本gotopage变量XSS ROOTKIT 0DAY

影响版本&#xff1a; DEDECMS全版本 漏洞描叙&#xff1a; DEDECMS后台登陆模板中的gotopage变量未效验传入数据&#xff0c;导致XSS漏洞。 \dede\templets\login.htm 65行左右 <input type"hidden" name"gotopage" value"<?php if(!empty($g…

Android开源库loopj的android-async-http的 JsonHttpResponseHandler 存在死循环GC_CONCURRENT

我现在用的是 AndroidAsyncHttp 1.4.4 版本&#xff0c;之前遇到一个很奇怪的问题&#xff0c; 当使用 JsonHttpResponseHandler 解析请求的页面出现服务器错误或其他情况返回的内容不是 JSON 字符串时不会调用自己复写实现的 onSuccess 或者 onFailure 方法&#xff0c;将会出…

进程状态转换(了解)

进程三个基本状态&#xff1a;就绪、阻塞、运行 这个比较简单&#xff0c;进程创建后进入就绪状态、然后若CPU空闲或能打断CPU正在执行的进程&#xff08;优先级低的&#xff09;&#xff0c;那么就绪状态转换成运行态&#xff0c;运行时&#xff0c;进程需要用到其他资源&…

2014阿里巴巴校园招聘笔试题 - 中南站

转载于:https://www.cnblogs.com/gotodsp/articles/3530329.html

Spring的IOC原理[通俗解释一下]

1. IoC理论的背景 我们都知道&#xff0c;在采用面向对象方法设计的软件系统中&#xff0c;它的底层实现都是由N个对象组成的&#xff0c;所有的对象通过彼此的合作&#xff0c;最终实现系统的业务逻辑。 图1&#xff1a;软件系统中耦合的对象 如果我们打开机械式手表的后盖&am…

以嵌入式系统设计师考试成绩,开始嵌入式博客之旅

http://www.rkb.gov.cn/jsj/cms/s_contents/download/s_dt201003110106.html 转载于:https://www.cnblogs.com/yueqian-scut/p/3952268.html

SSH框架配置及Maven使用

1.SSH框架配置 1.1. SSH框架介绍 1.2. SSH框架配置 所需资源下载&#xff1a; l jdk; 从Oracle官方网站&#xff1a;http://www.oracle.com/technetwork/cn/java/javase/downloads/index.html下载jdk&#xff0c;win7是默认安装在C:\Program Files (x86)\Java\jdk1.6.0_25路径下…

Flask 从入门到熟悉(不敢称为精通)

文章目录2.1 Flask介绍及其安装2.2 Virtualenv3.1 一个最小的应用3.2 外部课件服务器3.3 调试模式4.1 路由介绍4.2 变量规则4.3 构建URL4.4 HTTP 方法4 总结5.1 静态文件5.2 渲染模板5.3 练习66.1 接收请求数据6.2 请求对象6.3 文件上传6.4 Cookies6 总结77.1 重定向和错误7.2 …