ZOJ2112--Dynamic Rankings (动态区间第k大)
Dynamic Rankings
Time Limit: 10 Seconds Memory Limit: 32768 KB
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.
Your task is to write a program for this computer, which
- Reads N numbers from the input (1 <= N <= 50,000)
- Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.
Input
The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.
The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format
Q i j k or
C i t
It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.
There're NO breakline between two continuous test cases.
Output
For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])
There're NO breakline between two continuous test cases.
Sample Input
2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
3
6
主席树动态第k大基本可以手写,,但是感觉理解还不是很深。另外定义两个数组,一个用来新建一颗主席树,所有修改的结果都在这个上面进行,而另一个是记录中间值,相当于temp的效果,不改变原始数组。。(挖个坑)
附主席树专题链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=63941#overview
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 5e4+;
int n,m,tot,idx;
ll a[maxn],vec[maxn*];
struct
{
int x,y,k,flag,idx;
} Q[maxn]; // 主席树
int lson[maxn*],rson[maxn*],c[maxn*],root[maxn]; //依次为左儿子 右儿子 线段树 根节点
int build (int l,int r)
{
int root = tot++;
c[root] = ;
if (l != r)
{
int mid = (l + r) >> ;
lson[root] = build(l,mid);
rson[root] = build(mid+,r);
}
return root;
}
int update(int root,int pos,int val)
{
int new_root = tot++;
int tmp = new_root;
int l = ,r = idx;
c[new_root] = c[root] + val;
while (l < r)
{
int mid = (l + r) >> ;
if (pos <= mid)
{
rson[new_root] = rson[root];
root = lson[root];
lson[new_root] = tot++;
new_root = lson[new_root];
r = mid;
}
else
{
lson[new_root] = lson[root];
root = rson[root];
rson[new_root] = tot++;
new_root = rson[new_root];
l = mid + ;
}
c[new_root] = c[root] + val;
}
return tmp;
}
// 树状数组维护
int s[maxn],use[maxn];
inline int lowbit (int x)
{
return x & -x;
}
void add(int k,int pos,int d)
{
while (k <= n)
{
s[k] = update(s[k],pos,d);
k += lowbit(k);
}
}
int sum(int pos)
{
int res = ;
while (pos)
{
res += c[lson[use[pos]]];
pos -= lowbit(pos);
}
return res;
}
int query(int left,int right,int k)
{
int l_root = root[left-];
int r_root = root[right];
for (int i = left-; i > ; i -= lowbit(i))
use[i] = s[i];
for (int i = right; i > ; i -= lowbit(i))
use[i] =s[i];
int l = ,r = idx;
while (l < r)
{
int t = sum(right) - sum(left-) + c[lson[r_root]] - c[lson[l_root]];
int mid = (l + r) >> ;
if (t >= k)
{
for (int i = left-; i > ; i -= lowbit(i))
use[i] = lson[use[i]];
for (int i = right; i > ; i -= lowbit(i))
use[i] = lson[use[i]];
l_root = lson[l_root];
r_root = lson[r_root];
r = mid;
}
else
{
for (int i = left-; i > ; i -= lowbit(i))
use[i] = rson[use[i]];
for (int i = right; i > ; i -= lowbit(i))
use[i] = rson[use[i]];
l_root = rson[l_root];
r_root = rson[r_root];
k -= t;
l = mid + ;
}
}
return l;
} void read()
{
scanf ("%d%d",&n,&m);
for (int i = ; i <= n; i++)
{
scanf ("%lld",a+i);
vec[idx++] = a[i];
}
for (int i = ; i < m; i++)
{
char op[];
scanf ("%s",op);
if (op[] == 'C')
{
scanf ("%d%d",&Q[i].x,&Q[i].y);
Q[i].flag = ;
vec[idx++] = Q[i].y;
}
if (op[] == 'Q')
{
scanf ("%d%d%d",&Q[i].x,&Q[i].y,&Q[i].k);
Q[i].flag = ;
}
}
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
scanf ("%d",&T);
while (T--)
{
idx = tot = ;
read();
sort(vec,vec+idx); //离散化
idx = unique(vec,vec+idx) - vec;
root[] = build(,idx);
for (int i = ; i <= n; i++)
{
int tmp = lower_bound(vec,vec+idx,a[i]) - vec ;
root[i] = update(root[i-],tmp,);
}
for (int i = ; i <= n; i++)
s[i] = root[];
for (int i = ; i < m; i++)
{
if (Q[i].flag == )
{
int tmp1 = lower_bound(vec,vec+idx,a[Q[i].x]) - vec ;
int tmp2 = lower_bound(vec,vec+idx,Q[i].y) - vec ;
add(Q[i].x,tmp1,-);
add(Q[i].x,tmp2,);
a[Q[i].x] = Q[i].y;
}
if (Q[i].flag == )
{
printf("%lld\n",vec[query(Q[i].x,Q[i].y,Q[i].k)]);
}
}
}
return ;
}
ZOJ2112--Dynamic Rankings (动态区间第k大)的更多相关文章
- ZOJ2112 Dynamic Rankings 动态区间第K最值 平方分割
有了上一题的经验(POJ的静态区间第K最值)再解决这道题就轻松多了 空间5256KB,时间3330ms,如果把动态开点的平衡树换成数组模拟的话应该会更快 之所以选择了平方分割而不是树套树,不仅是所谓趁 ...
- ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】
题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题意: 求动态区间第K大. 分析: 把修改操作看成删除与增加 ...
- hdu5412(动态区间第k大)
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- 整体二分求动态区间第k大
比树状数组套主席树不知道高到哪里去了,solve(l,r,L,R)就是对于L,R的操作区间的答案都在l,r区间里,然后递归下去 复杂度O(nlognlogn),每个操作会执行logn次就是o(nlog ...
- Dynamic_Rankings(动态区间第k大)
ZOJ - 2112 \[ \ \] (那些说这道题是树状数组套主席树的人一定对主席树有误解!) 这里我们用树状数组套线段树来解决来写 首先 , 我们需要有n棵线段树(不是\(n^2\)空间,别慌) ...
- 动态区间第K大
整体二分. 主要需要注意的一点是,对于每个删除操作,若删除操作被算入贡献,则最开始的插入操作也一定会被算入,所以不必担心删除删错. #include<cstdio> #include< ...
随机推荐
- iomanip
在c++程序里面经常见到下面的头文件 #include <iomanip> io代表输入输出,manip是manipulator(操纵器)的缩写(在c++上只能通过输入缩写才有效.) 2作 ...
- There is already an open DataReader associated with this Connection which must be closed first
使用MVC4 EF Linq获取foreach列表循环的时候遇到了如下的问题:报错提示 There is already an open DataReader associated with this ...
- CSS简要内容
1. 简介 用于布局与美化网页(颜色,字体) CSS语言是一种标记语言,不需编译,可直接由浏览器执行 大小写不敏感 CSS定义由选择符.属性.属性取值组成 格式:selector{property:v ...
- 【※索引】mysql索引常用命令
索引分单列索引和组合索引.单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引.组合索引,即一个索包含多个列. MySQL索引类型包括: (1)普通索引 这是最基本的索引,它没 ...
- Oracle中包的创建
包是过程和函数的集合体,包包括创建包和创建包体,创建包的时候在可以定义过程和函数,包体中则具体实现过程和函数. eg: --创建包 create or replace package mypac1 ...
- 关于iOS应用管理之九宫格的坐标计算以及与UIScrollView的结合
关于九宫格的布局以及坐标的计算,对于大多数的iOS初学者甚至有一定能力的学者来说都是一大难题,在此写者通过自己的开发经验以及多次应用,把自己的所学所得分享给大家,就通过应用管理来进行浅谈一二. ...
- iOS9中请求出现App Transport Security has blocked a cleartext HTTP (http://)
错误描述: App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecu ...
- [转载] 与WIN不同,linux替换文件夹会删除原文件夹下的全部内容!
今天差点把源码给覆盖掉了><...555... 虚惊一场!!看了一篇博客分析这种情况.我的环境是CentOS5.5,不会出现文件夹直接被覆盖的情况,但是在Linux下不要用Win下的一些直 ...
- 解决百度Ueditor编辑器表格不显示边框问题
一.主要内容 CMS使用百度Ueditor编辑器中的表格功能,在编辑模式下可以正常显示边框,而文章发布之后表格不能显示边框.本博文经过查阅相关资料,最终解决了该问题. 二.使用平台 1. dedecm ...
- angular 引入 component 报错
每天抽出一些时间学习 Angular2 ,并准备把手头上的项目移植为 Angular2 , 不过今天又遇到了一些小问题. 准备写一个导航类适于管理后台常见的右边导航,如博客园的这种: ! 使用 g g ...