POJ2104 K-th Number(整体二分)
嘟嘟嘟
整体二分是一个好东西。
理解起来还行。
首先,需要牢记的是,我们二分的是答案,也就是在值域上二分,同时把操作分到左右区间中(所以操作不是均分的)。
然后我就懒得讲了……
李煜东的《算法竞赛进阶指南》第二版中讲的特别好,有兴趣的OIer可以拿来读读。
这里贴一个板儿。
突然想说一嘴:这道题我们应该保证所有修改(赋值)操作在询问操作之前。虽然代码中没有明显的排序,但是因为读入的时候就先把赋值操作放进操作队列里了,所以二分的每一层,询问区间中一定先是修改,再是询问。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const int Max = 1e9;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, m, cnt = 0;
struct Node
{
int x, y, k, id;
}t[maxn << 1], tl[maxn << 1], tr[maxn << 1];
int ans[maxn];
int c[maxn];
int lowbit(int x) {return x & -x;}
void clear(int pos)
{
for(; pos <= n; pos += lowbit(pos))
if(c[pos]) c[pos] = 0;
else return;
}
void update(int pos, int d)
{
for(; pos <= n; pos += lowbit(pos)) c[pos] += d;
}
int query(int pos)
{
int ret = 0;
for(; pos; pos -= lowbit(pos)) ret += c[pos];
return ret;
}
void solve(int l, int r, int ql, int qr)
{
if(ql > qr) return;
if(l == r)
{
for(int i = ql; i <= qr; ++i)
if(t[i].id) ans[t[i].id] = l;
return;
}
int mid = (l + r) >> 1;
int id1 = 0, id2 = 0;
for(int i = ql; i <= qr; ++i)
{
if(!t[i].id)
{
if(t[i].k <= mid) update(t[i].x, 1), tl[++id1] = t[i];
else tr[++id2] = t[i];
}
else
{
int sum = query(t[i].y) - query(t[i].x - 1);
if(sum >= t[i].k) tl[++id1] = t[i];
else t[i].k -= sum, tr[++id2] = t[i];
}
}
for(int i = ql; i <= qr; ++i) if(!t[i].id && t[i].k <= mid) clear(t[i].x);
for(int i = 1; i <= id1; ++i) t[ql + i - 1] = tl[i];
for(int i = 1; i <= id2; ++i) t[ql + id1 + i - 1] = tr[i];
solve(l, mid, ql, ql + id1 - 1);
solve(mid + 1, r, ql + id1, qr);
}
int main()
{
n = read(); m = read();
for(int i = 1; i <= n; ++i) t[++cnt].x = i, t[cnt].k = read(), t[cnt].id = 0;
for(int i = 1; i <= m; ++i)
t[++cnt].x = read(), t[cnt].y = read(), t[cnt].k = read(), t[cnt].id = i;
solve(-Max, Max, 1, cnt);
for(int i = 1; i <= m; ++i) write(ans[i]), enter;
return 0;
}
POJ2104 K-th Number(整体二分)的更多相关文章
- POJ2104 K-th Number [整体二分]
题目传送门 K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 69053 Accepted: 24 ...
- POJ2104 K-th Number(整体二分)
题解 又一次做这个题上一次用的是线段树上二分.这次用的是整体二分.结果: (第一个是整体二分) 整体二分就是对于所有查询都二分一个值.然后根据能不能成立把询问修改分成两部分,然后第二部分继承第一部分的 ...
- 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 ...
- ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】
题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题意: 求动态区间第K大. 分析: 把修改操作看成删除与增加 ...
- [ZJOI2013]K大数查询——整体二分
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是: 1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c 2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少. ...
随机推荐
- Jquery停止动画
stop方法 第一个参数:是否清除动画队列 true | false 第二个参数:是否跳转到动画最终效果 true | false 使用stop()方法的技巧 当下拉菜单和手风琴产生动画队列的问题 ...
- Docker 为 ASP.NET Core Web 应用程序生成 Docker 映像,创建并运行多个容器
1.为 ASP.NET Core 应用程序生成 Docker 映像 下载这个事例项目:https://github.com/dotnet/dotnet-docker/tree/master/sampl ...
- Maven的配置与下载
一丶下载 前提条件 :已经安装配置好了Jdk 进入maven官网选择自己看上的版本:http://maven.apache.org/ 下载后解压开始配置环境! 二丶配置环境变量 新建系统变量 其实不建 ...
- c3p0 配置文件的设置。解决编码乱码问题等
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <named-confi ...
- servlet 中处理 json 请求,并访问 service 类,返回处理结果
前言:jar 包中的 servlet 必须可以处理前端发出的 ajax 请求,接收参数,并返回结果. github地址:yuleGH github 这里有个约定,url 地址是 .json 结尾的,如 ...
- Android8自定义广播无法收到消息
在Android 8之前,如果要发送自定义的静态广播,做好其他配置后,只需实例化一个Intent对象intent,然后将其作为参数传入sendBroadcast()方法中即可,例如 Intent in ...
- 微信小程序 发现之旅(二)—— 自定义组件
组件化的项目开发中,组件应当划分为三个层次:组件.模块.页面 微信小程序已经为开发者封装好了基础组件,页面文件(pages)也有了详细的规定 而模块就需要自行开发,并且要和页面文件区分开,这就涉及到自 ...
- 获取url地址的参数值
使用频率很高,百度了记录一下 $.getUrlParam = function (name) { var reg = new RegExp("(^|&)" + name + ...
- html前端学习
html : 1.相当于没有穿衣服的人,一套浏览器认识的规则, 2.开发者: 学习html规则 开发后台程序: -写html文件(充当模板) -数据库获取数据,然后替换到html文件的指定位置(web ...
- (二)收集的MongoDB命令集合
一:针对整个数据库的 1."show dbs" 命令可以显示所有数据的列表. 2. "db" 命令可以显示当前数据库对象或集合. 3."use&quo ...