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 ...
随机推荐
- c# 发送Email的2中方式
先来第一种 // 版权所有 ZhuoYue Co.,Ltd 卓越一通秘密信息 // 文件名称:MyEmailByCDO.cs // 作 者:huangzh // 创建日期:2015-08-20 16: ...
- 事件聚合IEventAggregator和 Ihandle<T>
-事件聚合IEventAggregator和 Ihandle<T> 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇 ...
- hdu 2159
二维背包,dp[i][j]表示忍耐度为i,且还可以杀j个怪时能获得的最大经验值 dp[i][j]=max(dp[i][j],dp[i-r[k]][j-1]+e[k]),r[k]为杀死第k种怪掉的忍耐度 ...
- poj2236无线网络
这一题的大意:在救灾当中需要用网络,这堆人就用笔记本建了一个无线网,但是来,互相通信都是有距离限制的,一台电脑只能和距离他为d的电脑通信,然后一台电脑也可以通过几台电脑搭成线这样通信.然后就是输入每台 ...
- CSS3:三个矩形,一个宽200px,其余宽相等且自适应满铺
某公司面试题:下图绿色区域的宽度为100%,其中有三个矩形,第一个矩形的宽度是200px,第二个和第三个矩形的宽度相等.使用CSS3中的功能实现它们的布局. 这里要用到的CSS3特性box-flex ...
- javascript的关键所在---作用域链
javascript的关键所在---作用域链 javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript ...
- No CurrentSessionContext configured 异常解决
Exception in thread "main" org.hibernate.HibernateException: No CurrentSessionContext conf ...
- Jquery多级菜单插件Slimmenu使用说明
Jquery多级菜单插件Slimmenu使用说明 现在扁平化设计逐渐的成为了趋势,不管是pc web,还是移动互联网的应用开发,都在研究和设计Flat ui, 这里有一篇文章说明扁平化的设计的一些想法 ...
- ASP.NET MVC C#知识点提要
ASP.NET MVC C#知识点提要 本篇博文主要对asp.net mvc开发需要撑握的C#语言知识点进行简单回顾,尤其是C# 3.0才有的一些C#语言特性.对于正在学asp.net mvc的童鞋, ...
- TOGAF架构内容框架之概述及架构工作产品分类
TOGAF架构内容框架之概述及架构工作产品分类 在TOGAF 9之前的版本中,TOGAF的重点主要集中在企业架构开发方法方面,用于指导其使用者如何在各自的组织中对企业架构进行创建和维护,而对于企业架构 ...