【ZOJ2112】【整体二分+树状数组】带修改区间第k大
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大也应该可以做了。
不过这题的经典作法是树状数组上套可持久化线段树,不过这样空间消耗会很大。
可能要用动态开点?
转一个用块状链表的:http://www.cnblogs.com/zhj5chengfeng/archive/2013/08/19/3268162.html
/*
宋代晏殊
《蝶恋花·槛菊愁烟兰泣露》 槛菊愁烟兰泣露。罗幕轻寒,燕子双飞去。明月不谙离恨苦。斜光到晓穿朱户。
昨夜西风凋碧树。独上高楼,望尽天涯路。欲寄彩笺兼尺素。山长水阔知何处。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int INF = ;
const int MAXN = + ;
using namespace std;
struct QUERY{
int x, y;
int k, s, type, cur;//cur用来记录前面的值
}q[MAXN], q1[MAXN], q2[MAXN];
int Ans[MAXN];
int tmp[MAXN], c[MAXN];
int n, m, num, cnt;
int data[MAXN]; inline int lowbit(int x){return x&-x;}
void add(int x, int val){
while (x <= n){
c[x] += val;
x += lowbit(x);
}
return;
}
int sum(int x){
int cnt = ;
while (x > ){
cnt += c[x];
x -= lowbit(x);
}
return cnt;
}
//整体二分
void solve(int l, int r, int L, int R){
//这两个都是结束条件
if (l > r) return;
if (L == R){//更新答案
for (int i = l; i <= r; i++)
if (q[i].type == ) Ans[q[i].s] = L;
return;
}
int mid = (L + R) >> ;
for (int i = l; i <= r; i++){
if (q[i].type == && q[i].y <= mid) add(q[i].x, );
else if (q[i].type == && q[i].y <= mid) add(q[i].x, -);
else if (q[i].type == ) tmp[i] = sum(q[i].y) - sum(q[i].x - );
}
//更新完了就要清除标记了
for (int i = l; i <= r; i++){
if (q[i].type == && q[i].y <= mid) add(q[i].x, -);
else if (q[i].type == && q[i].y <= mid) add(q[i].x, );
}
int l1 = , l2 = ;
for (int i = l; i <= r; i++){
if (q[i].type == ){
//不用id就直接改
if (q[i].cur + tmp[i] > q[i].k - ) q1[++l1] = q[i];
else {
q[i].cur += tmp[i];
q2[++l2] = q[i];
}
}else{
if (q[i].y <= mid) q1[++l1] = q[i];
else q2[++l2] = q[i];
}
}
for (int i = ; i <= l1; i++) q[i + l - ] = q1[i];
for (int i = ; i <= l2; i++) q[i + l1 + l - ] = q2[i];
solve(l, l + l1 - , L, mid);
solve(l + l1, r, mid + , R);
}
void init(){
memset(c, , sizeof(c));
cnt = num = ;//指针初始化,num记录总的操作数量
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++){
num++;
scanf("%d", &data[i]);
q[num].x = i;q[num].type = ;//1代表插入
q[num].s = ;q[num].y = data[i];//没有用y就当val用
}
for (int i = ; i <= m; i++){
char str[];
num++;
scanf("%s", str);
if (str[] == 'Q'){
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
q[num].x = l;q[num].y = r;
q[num].type = ; q[num].s = ++cnt;
q[num].k = k;
}else{
int l, x;
scanf("%d%d", &l, &x);
q[num].x = l;q[num].y = data[l];//2为删除
q[num].type = ;q[num].s = ;
q[++num].x = l;
q[num].y = x;//删除后插入
q[num].type = ;
q[num].s = ;
data[l] = x;//注意这里一定要改,不然会影响到后面的更新
}
}
for (int i = ; i <= num; i++) q[i].cur = ;
} int main(){
int T; scanf("%d", &T);
while (T--){
init();
solve(, num, , INF);
for (int i = ; i <= cnt; i++) printf("%d\n", Ans[i]);
}
return ;
}
【ZOJ2112】【整体二分+树状数组】带修改区间第k大的更多相关文章
- 主席树套树状数组——带修区间第k大zoj2112
主席树带修第k大 https://www.cnblogs.com/Empress/p/4659824.html 讲的非常好的博客 首先按静态第k大建立起一组权值线段树(主席树) 然后现在要将第i个值从 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- 【BZOJ-2527】Meteors 整体二分 + 树状数组
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 831 Solved: 306[Submit][Stat ...
- 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组
题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...
- BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组
BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小
少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...
- BZOJ 2527 [POI2011]MET-Meteors (整体二分+树状数组)
题目大意:略 洛谷传送门 整体二分裸题 考虑只有一个国家的情况如何处理 对询问数量二分答案,暴力$O(m)$打差分,求前缀和验证,时间是$O(mlogK)$ 如果有$n$个国家,就是$O(nmlogK ...
随机推荐
- ACM2096
#include<iostream> int main() { using namespace std; int a,b,count; cin>>count; while(co ...
- xapian搜索系统存储结构解读
Xapian的database是所有用于检索的信息表的集合,以下的表是必需的: posting list table 保存了被每一个term索引的document,实际上保存的应该是document在 ...
- Xmpp integration with Asterisk
http://gnu-linux.org/xmpp-integration-with-asterisk.html Xmpp stands for eXtensible Messaging and Pr ...
- 图形变幻矩阵 Transforms
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d ...
- 你不一定能做对的JavaScript闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- XML文件操作指南
一.XML简介 XML的全名是eXtensible Markup Language(可以扩展的标记语言),它的语法类似HTML,都是用标签来描述数据.HTML的标签是固定的,我们只能使用.不能修改: ...
- [转载]通过jQuery的attr修改onclick
var js = "alert('B:' + this.id); return false;"; // creates a function from the "js&q ...
- Oracle分页查询SQL实现
首先看SQL 怎么写 select * from ( select a.*,ROWNUM rn from ( 最底层查询语句 ) a where ROWNUM <= #{endCol} ) wh ...
- 怎样给filter加入自己定义接口及调用
本样例是在VirtualCamera的基础上加入的自己定义接口用来实现exe控制osd的显示. 1. 接口部分 #ifndef __H_MyFilter__#define __H_MyFilter__ ...
- 将.lib库文件转换成.a库文件的工具
分享如下两个链接: 微盘: http://vdisk.weibo.com/s/ztzPTJIC52mz2 百度云盘: http://pan.baidu.com/s/11gTOc 使用方法,解压文件mi ...