整体二分初识--POJ2104:K-th Number
n<=100000个数有m<=5000个询问,每次问区间第k大。
方法一:主席树!……
方法二:整体二分。
整体二分一次性计算半个值域对一个区间的询问的贡献,然后根据“这半边的贡献在某个询问中可不可以直接处理掉”把询问分两部分,并按“数字的值是否在这半边”把数字也分成两部分,这样把一个区间和值域都分掉了,然后就可以在f(n)logMax的时间出解,其中f(n)表示计算一次这样的贡献需要的时间。
在这题里,只需要看某个区间里在值域[L,mid]中出现的数字的个数有没有到K个,以此划分成两个区域。因此树状数组搞一搞,f(n)=nlogn,大功告成。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 //#include<bitset> 6 #include<algorithm> 7 //#include<cmath> 8 using namespace std; 9 10 int n,m; 11 #define maxn 200011 12 const int inf=0x3f3f3f3f; 13 struct App 14 { 15 int x,y,z,id,type; 16 //type=1 表示修改,其中x为位置,y为数值,z为在bit中的修改权值 17 //type=0 表示询问,其中x,y为左右端点,z是第几大,id询问编号 18 }a[maxn],al[maxn],ar[maxn]; 19 int ans[maxn]; 20 21 struct BIT 22 { 23 int a[maxn]; 24 void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;} 25 int query(int x) {int ans=0; for (;x;x-=x&-x) ans+=a[x]; return ans;} 26 }t; 27 28 void solve(int L,int R,int ql,int qr) 29 { 30 if (ql>qr || L>R) return; 31 if (L==R) 32 { 33 for (int i=ql;i<=qr;i++) ans[a[i].id]=L; 34 return; 35 } 36 const int mid=(L+R)>>1; 37 int lal=0,lar=0; 38 for (int i=ql;i<=qr;i++) 39 { 40 if (a[i].type) 41 { 42 if (a[i].y<=mid) 43 { 44 t.add(a[i].x,a[i].z); 45 al[++lal]=a[i]; 46 } 47 else ar[++lar]=a[i]; 48 } 49 else 50 { 51 int tmp=t.query(a[i].y)-t.query(a[i].x-1); 52 if (tmp>=a[i].z) al[++lal]=a[i]; 53 else 54 { 55 ar[++lar]=a[i]; 56 ar[lar].z-=tmp; 57 } 58 } 59 } 60 for (int i=1;i<=lal;i++) if (al[i].type==1) t.add(al[i].x,-al[i].z); 61 for (int i=1,j=ql;i<=lal;i++,j++) a[j]=al[i]; 62 for (int i=1,j=ql+lal;i<=lar;i++,j++) a[j]=ar[i]; 63 solve(L,mid,ql,ql+lal-1); 64 solve(mid+1,R,ql+lal,qr); 65 } 66 67 int main() 68 { 69 scanf("%d%d",&n,&m); 70 for (int i=1;i<=n;i++) scanf("%d",&a[i].y),a[i].x=i,a[i].z=1,a[i].type=1; 71 for (int i=1,j=n+1;i<=m;i++,j++) scanf("%d%d%d",&a[j].x,&a[j].y,&a[j].z),a[j].id=i,a[j].type=0; 72 solve(-inf,inf,1,n+m); 73 for (int i=1;i<=m;i++) printf("%d\n",ans[i]); 74 return 0; 75 }
View Code
转载于:https://www.cnblogs.com/Blue233333/p/8203399.html
整体二分初识--POJ2104:K-th Number相关推荐
- #4604. The kth maximum number(整体二分 + 树套树)
#4604. The kth maximum number 给定一个大小不超过5×1055 \times 10 ^ 55×105的矩形区域,有一些点有点权. 每次询问给定x1,y1,x2,y2,kx_ ...
- 经典题:poj2104-区间第k小 整体二分学习
写在前面 区间第k小 可以说是一个很经典的数据结构题了,这道题有很多种解法比如莫队离线.主席树.整体二分等等. 之前用莫队和主席树写过这道题,今天来学习一个以前不会的算法--整体二分. 因为最近遇到一 ...
- SP3946 MKTHNUM - K-th Number(整体二分)
思路 整体二分的板子题,没什么思路好说 代码 #include <cstdio> #include <algorithm> #include <cstring> u ...
- P3332 [ZJOI2013]K大数查询(整体二分做法)
P3332 [ZJOI2013]K大数查询 题意: 题解: 利用整体二分来做,这个题和P3834 [模板]可持久化线段树 2的区别在于本题的修改是区间修改,所以将里面的树状数组改成线段树就行,区间修改 ...
- 【整体二分】区间第k小(金牌导航 整体二分-1)
区间第k小 金牌导航 整体二分-1 题目大意 给出一个序列,有若干查询,每次查询给出l,r,k,让你求l~r这个区间的第k大 输入样例 7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 ...
- 【XSY2720】区间第k小 整体二分 可持久化线段树
题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...
- [ZJJOI2013]K大数查询 整体二分
[ZJJOI2013]K大数查询 链接 luogu 思路 整体二分. 代码 #include <bits/stdc++.h> #define ll long long using name ...
- BZOJ3110: [Zjoi2013]K大数查询(整体二分)
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- P2617 Dynamic Rankings 动态区间第K大【树套树】或【整体二分】
传送门 动态区间第KKK大问题,单点修改(这里是第kkk小,即是从小到大第kkk个) 这里还有个区间修改,有点类似的 P3332 [ZJOI2013]K大数查询 分析 树套树 树套树,就是用一种树形结 ...
- P3332 [ZJOI2013]K大数查询【整体二分】或【树套树】
传送门 给定一个长度为NNN的可重集合 支持修改,离线 求区间可重集合的并集第K大 这里介绍两种方法[树套树]和 [整体二分] 这里还有个单点修改,有点类似的 P2617 Dynamic Rankin ...
最新文章
- 《Programming WPF》翻译 第7章 3.笔刷和钢笔
- GPS数据转换为OneNet需要的数据
- Bzoj4817:[SDOI2017]树点涂色
- linux下wget命令(下载文件命令)
- [Everyday Mathematics]20150103
- mybatis学习(8):The server time zone value '???ú±ê×??±??' is unrecognized or represents more
- SqlServer学习之触发器
- 【转】Maven实战(八)---模块划分
- 一个java程序_从另一个java程序运行java程序
- Python 包管理工具poetry配置国内PyPI镜像源
- C++是C语言演变过来的,为何不能代替C语言?
- 惠普电脑笔记本台式机预装系统 V2011.08 兼容i3 i5 i7
- 移动app用户体验与性能优化
- linux iq测试题,ayawawa测试题
- 15分钟快速搭建属于自己的网站
- Windows文件资源管理器访问统信(UOS)虚拟机文件夹
- 如何解决安装或者卸载时 临时文件夹已满或不能访问
- 成为“高维空间”的人
- 蒲公英企服平台对话核盛网络刘涛——Tracup项目管理的一条生命线
- android 设置单边框,Android设置单边圆角边框
热门文章
- ImmunityDebugger 学习
- 潘正磊: 做最好、最美的你
- 设定MyEclipse编辑代码区域文字的大小及非关键字的字体、字形和颜色
- 在.Net中读写config文件的各种方法
- linux netcat命令实例
- C++ 预编译头文件stdafx.h
- list vue 添加数据方法_在PySpark数据框中添加新列的5种方法
- 位置度标注方法图解_追踪主力-散户操盘实战图解:操盘手法分析
- (day 38 - 双指针) 剑指 Offer 52. 两个链表的第一个公共节点
- qq里面cap字符_QQ 幸运字符一共有几种?