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相关推荐

  1. #4604. The kth maximum number(整体二分 + 树套树)

    #4604. The kth maximum number 给定一个大小不超过5×1055 \times 10 ^ 55×105的矩形区域,有一些点有点权. 每次询问给定x1,y1,x2,y2,kx_ ...

  2. 经典题:poj2104-区间第k小 整体二分学习

    写在前面 区间第k小 可以说是一个很经典的数据结构题了,这道题有很多种解法比如莫队离线.主席树.整体二分等等. 之前用莫队和主席树写过这道题,今天来学习一个以前不会的算法--整体二分. 因为最近遇到一 ...

  3. SP3946 MKTHNUM - K-th Number(整体二分)

    思路 整体二分的板子题,没什么思路好说 代码 #include <cstdio> #include <algorithm> #include <cstring> u ...

  4. P3332 [ZJOI2013]K大数查询(整体二分做法)

    P3332 [ZJOI2013]K大数查询 题意: 题解: 利用整体二分来做,这个题和P3834 [模板]可持久化线段树 2的区别在于本题的修改是区间修改,所以将里面的树状数组改成线段树就行,区间修改 ...

  5. 【整体二分】区间第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 ...

  6. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  7. [ZJJOI2013]K大数查询 整体二分

    [ZJJOI2013]K大数查询 链接 luogu 思路 整体二分. 代码 #include <bits/stdc++.h> #define ll long long using name ...

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

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

  9. P2617 Dynamic Rankings 动态区间第K大【树套树】或【整体二分】

    传送门 动态区间第KKK大问题,单点修改(这里是第kkk小,即是从小到大第kkk个) 这里还有个区间修改,有点类似的 P3332 [ZJOI2013]K大数查询 分析 树套树 树套树,就是用一种树形结 ...

  10. P3332 [ZJOI2013]K大数查询【整体二分】或【树套树】

    传送门 给定一个长度为NNN的可重集合 支持修改,离线 求区间可重集合的并集第K大 这里介绍两种方法[树套树]和 [整体二分] 这里还有个单点修改,有点类似的 P2617 Dynamic Rankin ...

最新文章

  1. 《Programming WPF》翻译 第7章 3.笔刷和钢笔
  2. GPS数据转换为OneNet需要的数据
  3. Bzoj4817:[SDOI2017]树点涂色
  4. linux下wget命令(下载文件命令)
  5. [Everyday Mathematics]20150103
  6. mybatis学习(8):The server time zone value '???ú±ê×??±??' is unrecognized or represents more
  7. SqlServer学习之触发器
  8. 【转】Maven实战(八)---模块划分
  9. 一个java程序_从另一个java程序运行java程序
  10. Python 包管理工具poetry配置国内PyPI镜像源
  11. C++是C语言演变过来的,为何不能代替C语言?
  12. 惠普电脑笔记本台式机预装系统 V2011.08 兼容i3 i5 i7
  13. 移动app用户体验与性能优化
  14. linux iq测试题,ayawawa测试题
  15. 15分钟快速搭建属于自己的网站
  16. Windows文件资源管理器访问统信(UOS)虚拟机文件夹
  17. 如何解决安装或者卸载时 临时文件夹已满或不能访问
  18. 成为“高维空间”的人
  19. 蒲公英企服平台对话核盛网络刘涛——Tracup项目管理的一条生命线
  20. android 设置单边框,Android设置单边圆角边框

热门文章

  1. ImmunityDebugger 学习
  2. 潘正磊: 做最好、最美的你
  3. 设定MyEclipse编辑代码区域文字的大小及非关键字的字体、字形和颜色
  4. 在.Net中读写config文件的各种方法
  5. linux netcat命令实例
  6. C++ 预编译头文件stdafx.h
  7. list vue 添加数据方法_在PySpark数据框中添加新列的5种方法
  8. 位置度标注方法图解_追踪主力-散户操盘实战图解:操盘手法分析
  9. (day 38 - 双指针) 剑指 Offer 52. 两个链表的第一个公共节点
  10. qq里面cap字符_QQ 幸运字符一共有几种?