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(整体二分)的更多相关文章

  1. POJ 2104:K-th Number 整体二分

    感觉整体二分是个很有趣的东西. 在别人的博客上看到一句话 对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了 树套树写了一天还是WA着,调得焦头烂额,所以决定学cd ...

  2. poj 3111 K Best 最大化平均值 二分思想

    poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件 ...

  3. POJ2104 K-th Number [整体二分]

    题目传送门 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 69053   Accepted: 24 ...

  4. BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

    有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...

  5. BZOJ3110:[ZJOI2013]K大数查询(整体二分)

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  6. BZOJ 3110 K大数查询 | 整体二分

    BZOJ 3110 K大数查询 题面 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个 ...

  7. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

  8. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  9. 静态区间第K小(整体二分、主席树)

    题目链接 题解 主席树入门题 但是这里给出整体二分解法 整体二分顾名思义是把所有操作放在一起二分 想想,如果求\([1-n]\)的第\(k\)小怎么二分求得? 我们可以二分答案\(k\), \(O(n ...

随机推荐

  1. PRML 第三章 - 线性回归

    这段时间组里在有计划地学习书籍PRML (Pattern Recognition and Machine Learning),前两天自己做了一个里面第三章linear regression的分享,这里 ...

  2. SSL协议的握手过程

    SSL握手的目的 第一,客户端与服务器需要就一组用于保护数据的算法达成一致. 第二,它们需要确立一组由那些算法所使用的加密密钥. 第三,握手还可以选择对客户端进行认证. SSL 握手概述 SSL 握手 ...

  3. .NET 微信开放平台接口(接收短信、发送短信)

    .NET 微信开放平台接口(接收短信.发送短信) 前两天做个项目用到了微信api功能.项目完成后经过整理封装如下微信操作类. 以下功能的实现需要开发者已有微信的公众平台账号,并且开发模式已开启.接口配 ...

  4. CSS属性合写

    animation:[[ animation-name ] || [ animation-duration ] || [ animation-timing-function ] || [ animat ...

  5. T4模板与数据访问层的分离

    当在企业级应用中使用EF时,会发现实体类库与数据访问层是分离的. 来一张效果图. 具体步骤: 1.运用EF生成原始的实体类 在程序集中添加完ADO.NET实体数据模型后,生成相应的实体类,此时,T4模 ...

  6. 尽量不用char*作为hash_map的key

    引子: 同事前几天用hash_map时发现一些问题.当时的场景是有一些字符串char*,要去对应某种类型的对象.同事的做法是: 尝试用char*作为key进行hash.编译通过,但运行时不正常,ins ...

  7. 记录下自己写的gulp打包脚本

    var c = { rootPath: 'src',//项目文件夹 outputPath: 'output',//文件编译后的输出目录 revPath: 'manifest',//rev映射文件目录 ...

  8. zoj 1610 Count the Colors(线段树延迟更新)

    所谓的懒操作模板题. 学好acm,英语很重要.做题的时候看不明白题目的意思,我还拉着队友一块儿帮忙分析题意.最后确定了是线段树延迟更新果题.我就欣欣然上手敲了出来. 然后是漫长的段错误.... 第一次 ...

  9. 使用ServletContextListener和HttpSessionListener两种监听器实现记录当前网站在线人数

    web.xml中配置: <listener>    <listener-class>com.mcm.listener.ServletContextListenerImpl< ...

  10. 函数sql黑马程序员——SQL常用函数

    最近使用开辟的过程中出现了一个小问题,顺便记录一下原因和方法--函数sql ---------------------- ASP.Net+Android+IO开辟S..Net培训.等待与您交流! -- ...