谈一下尺取法的经典题。

第K大区间

定义一个区间的值为其众数出现的次数。

现给出n个数,求将所有区间的值排序后,第K大的值为多少。

众数:区间里出现次数最多的数字,例如:1 1 2 2 2,区间[1 1]的众数为1,区间[3 5]的众数为2

题解

二分这个值,转化成判断问题。

将求第k大变成求第n*(n-1)/2-k+1小,那么我们就可以用尺取法计算值小于等于二分值的区间的个数。

区间

在数轴上有 n 个闭区间 [l1,r1], [l2,r2], . . . , [ln,rn]。现在要从中选出 m 个区间,使得这 m 个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区[li,ri],都有 li ≤ x ≤ ri

对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [li,ri] 的长度定义为 ri − li,即等于它的右端点的值减去左端点的值。

求所有合法方案中最小的花费。如果不存在合法的方案,输出 −1。

n ≤ 500000,m ≤ 200000.

题解

将坐标离散化之后,用线段树维护点的覆盖次数。

那么用尺取法即可求出最小花费。

CO int N=500000+10,M=2097152+10;
struct section {int l,r,len;}sec[N];
vector<int> pos;
int tree[M],tag[M];
#define lc (x<<1)
#define rc (x<<1|1)
IN void push_up(int x){
tree[x]=max(tree[lc],tree[rc]);
}
IN void push_down(int x){
if(tag[x]){
tree[lc]+=tag[x],tag[lc]+=tag[x];
tree[rc]+=tag[x],tag[rc]+=tag[x];
tag[x]=0;
}
}
void change(int x,int l,int r,int ql,int qr,int v){
if(ql<=l and r<=qr){
tree[x]+=v,tag[x]+=v;
return;
}
push_down(x);
int mid=(l+r)>>1;
if(ql<=mid) change(lc,l,mid,ql,qr,v);
if(qr>mid) change(rc,mid+1,r,ql,qr,v);
push_up(x);
}
int main(){
int n=read<int>(),m=read<int>();
for(int i=1;i<=n;++i){
read(sec[i].l),read(sec[i].r),sec[i].len=sec[i].r-sec[i].l;
pos.push_back(sec[i].l),pos.push_back(sec[i].r);
}
sort(sec+1,sec+n+1,[](CO section&a,CO section&b)->bool{
return a.len<b.len;
});
sort(pos.begin(),pos.end()),pos.erase(unique(pos.begin(),pos.end()),pos.end());
for(int i=1;i<=n;++i){
sec[i].l=lower_bound(pos.begin(),pos.end(),sec[i].l)-pos.begin()+1;
sec[i].r=lower_bound(pos.begin(),pos.end(),sec[i].r)-pos.begin()+1;
}
int ans=1e9;
for(int l=1,r=0;l<=n;++l){
while(r<n and tree[1]<m)
++r,change(1,1,pos.size(),sec[r].l,sec[r].r,1);
if(tree[1]==m) ans=min(ans,sec[r].len-sec[l].len);
change(1,1,pos.size(),sec[l].l,sec[l].r,-1);
}
if(ans==1e9) puts("-1");
else printf("%d\n",ans);
return 0;
}

51Nod1686 第K大区间 和 NOI2016 区间的更多相关文章

  1. 51nod-1686 第K大区间(二分+尺取法)

    题目链接: 第K大区间 基准时间限制:1 秒 空间限制:131072 KB    定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input 第一行两个数 ...

  2. 主席树入门——询问区间第k大pos2104,询问区间<=k的元素个数hdu4417

    poj2104找了个板子..,但是各种IO还可以进行优化 /* 找区间[l,r]第k大的数 */ #include<iostream> #include<cstring> #i ...

  3. 【大杀器】利用划分树秒杀区间内第k大的数

    最近看了一道题,大概就是给出一个序列,不断询问其子区间内第k大的数,下面是个截图 绕了一圈没找到中文版题目,if(你是大佬) then 去看截图:else{我来解释:给出一个整数n,和一个整数m,分别 ...

  4. 静态区间第k大 树套树解法

    然而过不去你谷的模板 思路: 值域线段树\([l,r]\)代表一棵值域在\([l,r]\)范围内的点构成的一颗平衡树 平衡树的\(BST\)权值为点在序列中的位置 查询区间第\(k\)大值时 左区间在 ...

  5. POJ 2388 Who's in the Middle (快速选择算法:O(N)求数列第K大)

    [题意]求数列中间项. ---这里可以扩展到数列第K项. 第一次做的时候直接排序水过了= =--这一次回头来学O(N)的快速选择算法. 快速选择算法基于快速排序的过程,每个阶段我们选择一个数为基准,并 ...

  6. 求数列中第K大的数

    原创 利用到快速排序的思想,快速排序思想:https://www.cnblogs.com/chiweiming/p/9188984.html array代表存放数列的数组,K代表第K大的数,mid代表 ...

  7. 区间第K大(一)

    Problem: 给定无序序列S:[b, e),求S中第K大的元素. Solution 1.裸排序 2.现将区间均分成两段,S1, S2,对S1,S2分别排序,然后

  8. [51nod1685]第k大区间

    Description 定义一个长度为奇数的区间的值为其所包含的的元素的中位数. 现给出$n$个数,求将所有长度为奇数的区间的值排序后,第$k$大的值为多少. Input 第一行两个数$n$和$k$. ...

  9. 数据结构2 静态区间第K大/第K小

    给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...

随机推荐

  1. 关于liveness服务依赖用法整理

    一.生产环境中部分服务的使用场景有前置条件 使用initContainers,做一些前置服务的检测动作,以确定前置服务已正常运行且能对外提供服务(若检测未通过则本pod无法启动) 使用liveness ...

  2. 用eclipse开发需要准备什么?

    1.到eclipse的官网上,https://www.eclipse.org/  下载好eclipse,安装好eclipse,修改eclipse.ini文件,把内存改大点,避免出现内存溢出的情况. [ ...

  3. Collection 接口的 toArray 方法

    Collection 接口的 toArray 方法 方法签名 Object[] toArray() 返回包含此 collection 中所有元素的数组. T[] toArray(T[] a) 返回包含 ...

  4. matlab利用m_map工具包画中国地图及散点云图

    开始之前需要准备好malab,中国地图shp文件,m_map工具包. 中国地图shp文件可以在下面的链接中下载: https://gadm.org/download_country_v3.html 本 ...

  5. Go在windows下执行命令行指令

    需要在Go写的服务里面调用命令行或者批处理,并根据返回的结果做处理. 在网上搜索了一翻,验证成功,现记录如下: cmd := exec.Command("cmd") // cmd ...

  6. 50道Redis面试题及答案整理,史上最全!

    在网上看到有关Redis的50道面试题,但是没有给出答案,之前我也在寻找这份Redis面试题的答案,今天特地把答案分享出来. 花了大量时间整理了这套Redis面试题及答案,希望对大家有帮助哈~ 弄明白 ...

  7. IDEA开发React环境配置

    概述 习惯了IDEA写代码,也不想在下一个webstorm,而且IDEA是webstorm的父集,webstorm能干的,IDEA应该也是可以的.本篇随便记录下idea下的react的环境搭建. 环境 ...

  8. 【1】【leetcode-139】【回溯超时、动态规划】单词拆分

    给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆分时可以重复使用字典中的单词.你可以假设字典中没有重复的 ...

  9. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

  10. C# 连接数据库的配置方法

    写在前面 在项目的开发过程中我门常常遇到会忘记数据库连接的配置的写法的尴尬处境.俗话说,好记性不如烂笔头.所以,mark一下. 1.Sqlserver数据库连接 <connectionStrin ...