ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】
题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112
题意:
求动态区间第K大。
分析:
把修改操作看成删除与增加,对所有操作进行整体二分。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define pr(x) cout << #x << ": " << x << " "
#define pl(x) cout << #x << ": " << x << endl;
const int maxn = 50000 + 5, maxq = 20000 + 5, oo = 0x3f3f3f3f;
int n, m, tot;
int a[maxn];
struct Query{
int x, y, k;
int id, type;
}q[maxn + maxq], q1[maxn + maxq], q2[maxn + maxq];
int bit[maxn];
int ans[maxq];
void add(int i, int x)
{
while(i <= n){
bit[i] += x;
i += i & -i;
}
}
int sum(int i)
{
int ans = 0;
while(i > 0){
ans += bit[i];
i -= i & -i;
}
return ans;
}
void solve(int ql, int qr, int l, int r)
{
if(ql > qr) return ;
if(l == r){
for(int i = ql; i <= qr; i++){
if(q[i].type == 2) ans[q[i].id] = l;
}
return ;
}
int t1 = 0, t2 = 0;
int mid = l + r >> 1;
// pl(mid);
for(int i = ql; i <= qr; i++){
if(q[i].type == 1){
if(q[i].x <= mid){
add(q[i].id, q[i].y);
q1[t1++] = q[i];
}else q2[t2++] = q[i];
}else{
int tmp = sum(q[i].y) -sum(q[i].x - 1);
if(tmp >= q[i].k) q1[t1++] = q[i];
else {
q[i].k -= tmp;
q2[t2++] = q[i];
}
}
}
for(int i = 0; i < t1; i++){
if(q1[i].type == 1) add(q1[i].id, -q1[i].y);
}
for(int i = 0; i < t1; i++) q[ql + i] = q1[i];
for(int i = 0; i < t2; i++) q[t1 + i + ql] = q2[i];
solve(ql, ql + t1 - 1, l, mid);
solve(ql + t1, qr, mid + 1, r);
}
int main (void)
{
int x;scanf("%d", &x);
while(x--){
scanf("%d%d", &n, &m);
tot = 0;
memset(bit, 0, sizeof(bit));
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
q[++tot] = (Query){a[i], 1, oo, i, 1};
}
char s[2];
int x, y, k;
int cnt = 0;
for(int i = 1; i <= m; i++){
scanf("%s%d%d", s, &x, &y);
if(s[0] == 'Q'){
scanf("%d", &k);
q[++tot] = (Query){x, y, k, ++cnt, 2};
}else{
q[++tot] = (Query){a[x], -1, oo, x, 1};
q[++tot] = (Query){y, 1, oo, x, 1};
}
}
solve(1, tot, 0, oo);
for(int i = 1; i <= cnt; i++){
printf("%d\n", ans[i]);
}
}
return 0;
}
ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】的更多相关文章
- 51nod 1175 区间第k大 整体二分
题意: 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 分析: 仅仅就是一道整体二分的入门题而已,没听说过整体二分? 其实就是一个分治的函数 ...
- ZOJ2112 Dynamic Rankings 动态区间第K最值 平方分割
有了上一题的经验(POJ的静态区间第K最值)再解决这道题就轻松多了 空间5256KB,时间3330ms,如果把动态开点的平衡树换成数组模拟的话应该会更快 之所以选择了平方分割而不是树套树,不仅是所谓趁 ...
- ZOJ2112--Dynamic Rankings (动态区间第k大)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- hdu5412(动态区间第k大)
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap
Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...
- 动态区间第K大
整体二分. 主要需要注意的一点是,对于每个删除操作,若删除操作被算入贡献,则最开始的插入操作也一定会被算入,所以不必担心删除删错. #include<cstdio> #include< ...
- 【XSY2720】区间第k小 整体二分 可持久化线段树
题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...
随机推荐
- CPP-基础:C++的new int()与new int[]
编写一个List类: class List { int length; //列表长度 int* lpInt; //列表指针 List(int size); ~List(); } List::List( ...
- js获得本季度的开始日期 结束日期
var now = new Date(); //当前日期var nowMonth = now.getMonth()+1; //当前月var nowYear = now.getFullYear(); / ...
- hibernate4+spring3+struts2搭建框架实例
1.所需要的JAR包 2.web.xml配置文件,这个和平时的配置是一样的 <?xml version="1.0" encoding="UTF-8"?&g ...
- 在tomcat中配置连接池
在tomcat的conf/Catalina/localhost目录下配置项目路径,tomcat启动是会直接根据配置去加载项目. 虽然配置就一句话,但经常忘,今天记下来. 如果你的项目成名是:mypro ...
- HDU-1312-Black and Red
这题其实和POJ的1979是同一道题,当时POJ使用cin写的,所以读入的时候,就很正确. 这次用scanf读入的时候,就出现了问题,我们在读完宽高之后,要用getchar吸收掉回车,然后每行末尾的回 ...
- Day13有参装饰器,三元表达式,匿名函数
多个装饰器: 加载顺序:由下而上 执行顺序:由上而下 有参装饰器: 闭包,给函数传参的一种方法 当装饰器内需要参数时,可以采用闭包形式给其传参,第三层函数接收完参数时,就变为无参装饰器 三元表达式: ...
- (原)剑指offer之旋转数组
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...
- c++ 快速幂 代码实现
懒得打代码系列… 不过这个代码挺短的死背下来也ok 解析在最下面 建议自己手动试个数据理解一下 比如 3^5 ^^ 原理:a ^ b = a ^ (b / 2) * 2 (b是奇数的话还要再乘一个a) ...
- Oracle中创建触发器示例及注意事项
1.oracle 中创建触发器示例 CREATE TABLE "CONCEPT"."FREQUENCYMODIFYLOG" ( "FREQUENCYI ...
- grunt与requirejs结合使用
// 多个js压缩成一个js // Project configuration. module.exports = function(grunt) { // 使用严格模式 'use strict'; ...