整体二分初识--POJ2104:K-th Number
n<=100000个数有m<=5000个询问,每次问区间第k大。
方法一:主席树!……
方法二:整体二分。
整体二分一次性计算半个值域对一个区间的询问的贡献,然后根据“这半边的贡献在某个询问中可不可以直接处理掉”把询问分两部分,并按“数字的值是否在这半边”把数字也分成两部分,这样把一个区间和值域都分掉了,然后就可以在f(n)logMax的时间出解,其中f(n)表示计算一次这样的贡献需要的时间。
在这题里,只需要看某个区间里在值域[L,mid]中出现的数字的个数有没有到K个,以此划分成两个区域。因此树状数组搞一搞,f(n)=nlogn,大功告成。
//#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
//#include<bitset>
#include<algorithm>
//#include<cmath>
using namespace std; int n,m;
#define maxn 200011
const int inf=0x3f3f3f3f;
struct App
{
int x,y,z,id,type;
//type=1 表示修改,其中x为位置,y为数值,z为在bit中的修改权值
//type=0 表示询问,其中x,y为左右端点,z是第几大,id询问编号
}a[maxn],al[maxn],ar[maxn];
int ans[maxn]; struct BIT
{
int a[maxn];
void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
int query(int x) {int ans=; for (;x;x-=x&-x) ans+=a[x]; return ans;}
}t; void solve(int L,int R,int ql,int qr)
{
if (ql>qr || L>R) return;
if (L==R)
{
for (int i=ql;i<=qr;i++) ans[a[i].id]=L;
return;
}
const int mid=(L+R)>>;
int lal=,lar=;
for (int i=ql;i<=qr;i++)
{
if (a[i].type)
{
if (a[i].y<=mid)
{
t.add(a[i].x,a[i].z);
al[++lal]=a[i];
}
else ar[++lar]=a[i];
}
else
{
int tmp=t.query(a[i].y)-t.query(a[i].x-);
if (tmp>=a[i].z) al[++lal]=a[i];
else
{
ar[++lar]=a[i];
ar[lar].z-=tmp;
}
}
}
for (int i=;i<=lal;i++) if (al[i].type==) t.add(al[i].x,-al[i].z);
for (int i=,j=ql;i<=lal;i++,j++) a[j]=al[i];
for (int i=,j=ql+lal;i<=lar;i++,j++) a[j]=ar[i];
solve(L,mid,ql,ql+lal-);
solve(mid+,R,ql+lal,qr);
} int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i].y),a[i].x=i,a[i].z=,a[i].type=;
for (int i=,j=n+;i<=m;i++,j++) scanf("%d%d%d",&a[j].x,&a[j].y,&a[j].z),a[j].id=i,a[j].type=;
solve(-inf,inf,,n+m);
for (int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}
整体二分初识--POJ2104:K-th Number的更多相关文章
- 模板—算法—整体二分(区间k小值)
模板—算法—整体二分(区间k小值) Code: #include <cstdio> #include <algorithm> using namespace std; #def ...
- [POJ2104] K – th Number (可持久化线段树 主席树)
题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...
- 整体二分初探 两类区间第K大问题 poj2104 & hdu5412
看到好多讲解都把整体二分和$CDQ$分治放到一起讲 不过自己目前还没学会$CDQ$分治 就单独谈谈整体二分好了 先推荐一下$XHR$的 <浅谈数据结构题的几个非经典解法> 整体二分在当中有 ...
- POJ2104 K-th Number —— 区间第k小 整体二分
题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS Memory Limit: 65536K Tota ...
- POJ2104 K-th Number [整体二分]
题目传送门 K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 69053 Accepted: 24 ...
- POJ2104 K-th Number(整体二分)
嘟嘟嘟 整体二分是一个好东西. 理解起来还行. 首先,需要牢记的是,我们二分的是答案,也就是在值域上二分,同时把操作分到左右区间中(所以操作不是均分的). 然后我就懒得讲了-- 李煜东的<算法竞 ...
- POJ2104 K-th Number(整体二分)
题解 又一次做这个题上一次用的是线段树上二分.这次用的是整体二分.结果: (第一个是整体二分) 整体二分就是对于所有查询都二分一个值.然后根据能不能成立把询问修改分成两部分,然后第二部分继承第一部分的 ...
- POJ2104 K-th number (整体二分)
刚学了整体二分,用这种解法来解决这道题. 首先对于每个询问时可以二分解决的,这也是可以使用整体二分的前提.将原来的序列看成是插入操作,和询问操作和在一起根据值域进行二分.用树状数组来检验二分值. 1 ...
- 【ZOJ2112】【整体二分+树状数组】带修改区间第k大
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
随机推荐
- 216 Combination Sum III 组合总和 III
找出所有可能的 k 个数,使其相加之和为 n,只允许使用数字1-9,并且每一种组合中的数字是唯一的.示例 1:输入: k = 3, n = 7输出:[[1,2,4]]示例 2:输入: k = 3, n ...
- D. Dasha and Very Difficult Problem 二分
http://codeforces.com/contest/761/problem/D c[i] = b[i] - a[i],而且b[]和a[]都属于[L, R] 现在给出a[i]原数组和c[i]的相 ...
- 开发一个 Web App 必须了解的那些事
在过去的一年里,我在从头开始开发我的第一个重要的Web应用.经验教会了很多以前不知道的东西,特别是在安全性和用户体验方面. 值得一提的是,我上一次尝试构建的任何合理复杂性是在2005年.所以,在安全防 ...
- HashMap和List遍历方法总结及如何遍历删除元素
https://blog.csdn.net/demohui/article/details/77748809
- TinyMCE编辑器
TinyMCE编辑器下载地址 http://www.tinymce.com/download/download.php
- spring 配置 shiro rememberMe
1.shiro 提供记住我的功能,当将form表单中name="rememberMe" 的value设为true或者登陆的token中.token.setRememberMe(tr ...
- CDN概述
- jquery 获取日期 date 对象、 判断闰年
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 原生 js 上传图片
js <!doctype html> <html> <head> <meta charset="utf-8"> <title& ...
- promise的简单使用
var p = new Promise(function (resolve,reject) { /*setTimeout(function () { resolve('success') },3000 ...