POJ 2104:K-th Number(整体二分)
http://poj.org/problem?id=2104
题意:给出n个数和m个询问求区间第K小。
思路:以前用主席树做过,这次学整体二分来做。整体二分在yr大佬的指点下,终于大概懂了点了。对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了。
在这题二分可行的答案,根据这个答案,把询问操作丢在左右两个队列里面分别递归继续按这样处理。注释里写的很详细。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int N = ;
const int INF = 0x3f3f3f3f;
struct P {
int type, l, r, val, id;
} q[N], lq[N], rq[N];
int ans[N], bit[N], sum[N], gap; int lowbit(int x) { return x & (-x); }
void update(int x, int w) { while(x <= gap) bit[x] += w, x += lowbit(x); }
int query(int x) { int ans = ; while(x) ans += bit[x], x -= lowbit(x); return ans; } void Solve(int lask, int rask, int l, int r) { // 整体二分答案,判断答案是否可行
if(rask < lask || r < l) return ;
if(l == r) // 如果找到合适的答案了,那么在这段区间的查询的全部答案都是属于它
{ for(int i = lask; i <= rask; i++) if(q[i].type == ) ans[q[i].id] = l; return ; }
int mid = (l + r) >> , lcnt = , rcnt = ;
for(int i = lask; i <= rask; i++) { // 遍历这段询问
if(q[i].type == ) { // 如果是插入
if(q[i].val <= mid) { // 因为查询的是第k小,那么就是升序排列的第k个数字
lq[++lcnt] = q[i]; // 如果插入的数比当前枚举的答案小,那么符合条件,在树状数组上插入并丢入左队列
update(q[i].id, );
} else rq[++rcnt] = q[i]; // 插入的数比当前枚举的答案大,对当前枚举的答案无影响,丢入右队列
} else { // 如果是询问
int num = query(q[i].r) - query(q[i].l - ); // 那么查询这段区间有多少个数
if(q[i].val <= num) lq[++lcnt] = q[i]; // 如果这段区间的数字比当前查询的k多,那么说明答案在左边
else { // 否则在右边,在右边的话还要减去左边拥有的
q[i].val -= num;
rq[++rcnt] = q[i];
}
}
}
for(int i = lask; i <= rask; i++) if(q[i].type == && q[i].val <= mid) update(q[i].id, -);
for(int i = ; i <= lcnt; i++) q[i+lask-] = lq[i]; // 重新构造
for(int i = ; i <= rcnt; i++) q[i+lask+lcnt-] = rq[i];
Solve(lask, lask + lcnt - , l, mid); // 分两边递归处理
Solve(lask + lcnt, rask, mid + , r);
} int main() {
int n, m, a, b, c;
scanf("%d%d", &n, &m); gap = n;
for(int i = ; i <= n; i++) {
scanf("%d", &a);
q[i] = (P){, , , a, i};
}
for(int i = ; i <= m; i++) {
scanf("%d%d%d", &a, &b, &c);
q[n+i] = (P){, a, b, c, i};
}
Solve(, n + m, -INF, INF);
for(int i = ; i <= m; i++) printf("%d\n", ans[i]);
return ;
}
POJ 2104:K-th Number(整体二分)的更多相关文章
- POJ 2104:K-th Number 整体二分
感觉整体二分是个很有趣的东西. 在别人的博客上看到一句话 对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了 树套树写了一天还是WA着,调得焦头烂额,所以决定学cd ...
- poj 3111 K Best 最大化平均值 二分思想
poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件 ...
- POJ2104 K-th Number [整体二分]
题目传送门 K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 69053 Accepted: 24 ...
- BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]
有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...
- BZOJ3110:[ZJOI2013]K大数查询(整体二分)
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- BZOJ 3110 K大数查询 | 整体二分
BZOJ 3110 K大数查询 题面 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个 ...
- BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)
题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
- 静态区间第K小(整体二分、主席树)
题目链接 题解 主席树入门题 但是这里给出整体二分解法 整体二分顾名思义是把所有操作放在一起二分 想想,如果求\([1-n]\)的第\(k\)小怎么二分求得? 我们可以二分答案\(k\), \(O(n ...
随机推荐
- [整理]在命令行执行 UIAutomation
instruments -t /Developer/Platforms/iPhoneOS.platform/Developer/Library/Instruments/PlugIns/Automati ...
- AsyncTasLoader不进行加载操作的原因及解决方法
使用AsyncTaskLoader加载数据.但是LoadInBackground却不会被回调.这是什么情况?我要怎么解决这个问题?如果你和我一样有这样的疑问.你可以移步至我的blog的这篇文章找到答案 ...
- ibatis-Spring 整合
这两天一直在研究ibatis与spring的整合 一个小小的demo搞的我头晕目眩的,但程序一旦跑起来了,突然有一种豁然开朗,重见天日,感觉生活很美好的感觉!,也许,这就是那一行行的代码带给我们的不同 ...
- 探讨 : Host在IIS上的WCF Service的执行方式
一个WCF请求由两个线程来完成 运行在IIS上的WCF service, 你可能会注意到一个比较有趣的现象. 当WCF service接收到一个请求时, 这个请求实际上会有两个线程在执行这个请求. 一 ...
- 在C中判断变量存储类型(字符常量/数组/动态变量)
在C中判断变量存储类型(字符常量/数组/动态变量) 在chinaunix论坛上有人问到关于变量存府类型的问题,我觉得可以写个测试代码加深大家对内存使用和布局的理解.下面我把原问题及处理办法贴出来,限供 ...
- LAMP编译安装遇到的问题
apache安装 1, no SSL-C headers found configure: error: ...No recognized SSL/TLS toolkit detected 解决办法: ...
- building android/ubuntu-touch on 32bit machine
host C: libhost <= build/libs/host/CopyFile.c host StaticLib: libhost (/media/linux/1/touch/expor ...
- java 子类、父类中静态代码块、字段,非静态代码块、字段以及构造函数的初始化顺序和次数
一个类中的数据初始化顺序是面试官非常喜欢出的面试题之一,本文用一个实例来介绍java中子类.父类中静态代码块.字段,非静态代码块.字段以及构造函数的执行顺序和次数. 一.包结构
- Linux编程之给你的程序开后门
这里说的"后门"并不是教你做坏事,而是让你做好事,搭建自己的调试工具更好地进行调试开发.我们都知道,当程序发生异常错误时,我们需要定位到错误,有时我们还想,我们在不修改程序的前提下 ...
- AI(三):微信与luis结合(上)
目录 基本原理 公众号申请及配置 验证服务器有效性 微信请求消息类型 基本原理 基本原理如上图:腾讯微信服务器就相当于一个转发服务器,终端(手机.Pad等)发起请求至微信服务器,微信服务器然后将请求转 ...