「NOI2016」区间 解题报告
「NOI2016」区间
最近思维好僵硬啊...
一上来就觉得先把区间拆成两个端点进行差分,然后扫描位置序列,在每个位置维护答案,用数据结构维护当前位置的区间序列,但是不会维护。
于是想研究性质,想到为什么要拿区间长度做权值呢,难道是有一些性质吗
于是思考了很久区间长度的性质,猜了一些sb结论,比如什么一个区间只有加入时和删除时的贡献算一下就可以了之类的...
全错了然后就自闭了...
然后想什么钦定最大值,然后询问位置区间,然后我发现线段树每个点要挂一个单调队列(事实上把单调队列从线段树上拿下来就是正解了,我当时一点都没想到),然后又自闭了
然后想干脆钦定最大最小值,反正只有\(n^2\)种,然后我们需要查询长度在最大最小值之间的区间,然后我们看一下这些区间的区间并有没有一个位置的值比\(m\)大,区间并可以染色,然后查询最大值
这样可以拿树套树暴力搞了,好像很对
然后发现如果扫描的最大值最小值两个指针的话,移动是\(O(n)\)的,好像叫尺取法把,然后就可以只维护一个线段树了。
Code:
#include <cstdio>
#include <cctype>
#include <algorithm>
using std::max;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
//#define gc() getchar()
template <class T>
void read(T &x)
{
	x=0;char c=gc();
	while(!isdigit(c)) c=gc();
	while(isdigit(c)) x=x*10+c-'0',c=gc();
}
void ckmin(int &x,int y){x=x<y?x:y;}
const int inf=0x3f3f3f3f;
const int N=5e5+10;
int n,m,k,saki[N<<1];
struct _toki
{
	int l,r,val;
	bool friend operator <(_toki a,_toki b){return a.val<b.val;}
}toki[N];
int mx[N<<3],tag[N<<3];
#define ls id<<1
#define rs id<<1|1
void pushdown(int id)
{
	if(tag[id])
	{
		mx[ls]+=tag[id],tag[ls]+=tag[id];
		mx[rs]+=tag[id],tag[rs]+=tag[id];
		tag[id]=0;
	}
}
void upt(int id,int L,int R,int l,int r,int d)
{
	if(r<L||l>R) return;
	if(l<=L&&R<=r)
	{
		mx[id]+=d;
		tag[id]+=d;
		return;
	}
	pushdown(id);
	int Mid=L+R>>1;
	upt(ls,L,Mid,l,r,d),upt(rs,Mid+1,R,l,r,d);
	mx[id]=max(mx[ls],mx[rs]);
}
int qry(int id,int L,int R,int l,int r)
{
	if(r<L||l>R) return 0;
	if(l<=L&&R<=r) return mx[id];
	pushdown(id);
	int Mid=L+R>>1;
	return max(qry(ls,L,Mid,l,r),qry(rs,Mid+1,R,l,r));
}
int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
	read(n),read(k);
	for(int i=1;i<=n;i++)
	{
		read(toki[i].l),read(toki[i].r);
		saki[++m]=toki[i].l,saki[++m]=toki[i].r;
		toki[i].val=toki[i].r-toki[i].l;
	}
	std::sort(saki+1,saki+1+m);
	m=std::unique(saki+1,saki+1+m)-saki-1;
	for(int i=1;i<=n;i++)
    {
        toki[i].l=std::lower_bound(saki+1,saki+1+m,toki[i].l)-saki;
        toki[i].r=std::lower_bound(saki+1,saki+1+m,toki[i].r)-saki;
    }
	std::sort(toki+1,toki+1+n);
	int l=1,r=1,ans=inf;
	while(r<=n)
	{
	    upt(1,1,m,toki[r].l,toki[r].r,1);
		while(qry(1,1,m,toki[r].l,toki[r].r)>=k)
		{
			ckmin(ans,toki[r].val-toki[l].val);
			upt(1,1,m,toki[l].l,toki[l].r,-1);
			++l;
		}
		++r;
	}
	if(ans==inf) puts("-1");
	else printf("%d\n",ans);
	return 0;
}
2019.5.30
「NOI2016」区间 解题报告的更多相关文章
- 「NOI2016」网格 解题报告
		
「NOI2016」网格 容易注意到,答案最多为2,也就是说答案为-\(1,0,1,2\)四种,考虑逐个判断. 无解的情况比较简单 如果\(nm\le c+1\),显然无解 如果\(nm=c+2\),判 ...
 - 「HNOI2016」树 解题报告
		
「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...
 - 「HNOI2016」序列 解题报告
		
「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...
 - 「SCOI2016」美味 解题报告
		
「SCOI2016」美味 状态极差无比,一个锤子题目而已 考虑每次对\(b\)和\(d\)求\(c=d \ xor \ (a+b)\)的最大值,因为异或每一位是独立的,所以我们可以尝试按位贪心. 如果 ...
 - 「SCOI2016」萌萌哒 解题报告
		
「SCOI2016」萌萌哒 这思路厉害啊.. 容易发现有个暴力是并查集 然后我想了半天线段树优化无果 然后正解是倍增优化并查集 有这个思路就简单了,就是开一个并查集代表每个开头\(i\)每个长\(2^ ...
 - 「NOI2014」购票 解题报告
		
「NOI2014」购票 写完了后发现写的做法是假的...然后居然过了,然后就懒得管正解了. 发现需要维护凸包,动态加点,询问区间,强制在线 可以二进制分组搞,然后你发现在树上需要资瓷撤回,然后暴力撤回 ...
 - 「NOI2017」整数 解题报告
		
「NOI2017」整数 有一些比较简单的\(\log^2n\)做法 比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位 ...
 - 「ZJOI2016」旅行者 解题报告
		
「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...
 - 「HNOI2016」网络 解题报告
		
「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...
 
随机推荐
- 多线程模拟生产者消费者示例之Lock
			
public class Test { public static void main(String[] args) { List<String> list = new ArrayList ...
 - tarjan-LCA模板
			
洛谷P3379 #include <cstdio> using namespace std; ; struct etype{ int t,next; }; struct qtype{ in ...
 - FPGA学习的一些误区
			
转载自网络,作者不详. 我常年担任多个有关FPGA学习研讨的QQ群管理员,长期以来很多新入群的菜鸟们总是在重复的问一些非常简单但是又让新手困惑不解的问题.作为管理员经常要给这些菜鸟们普及基础知识,但是 ...
 - cf1278D——树的性质+并查集+线段树/DFS判环
			
昨天晚上本来想认真打一场的,,结果陪女朋友去了.. 回来之后看了看D,感觉有点思路,结果一直到现在才做出来 首先对所有线段按左端点排序,然后用并查集判所有边是否联通,即遍历每条边i,和前一条不覆盖它的 ...
 - 用K-近邻算法分类和回归
			
import numpy as npfrom matplotlib import pyplot as plt X_train = np.array([ [158, 64], [170, 66], [1 ...
 - 使用ajax前必须了解的知识
			
ajax的全称: asynchronous javascript and xml (异步的javascript和xml) ajax不是某种编程语言 是一种在无需重新加载整个页面的情况下能够更新部分网页 ...
 - mybatis 插入
			
实体类 Mapper接口 void addUser(User user); Mapper.xml <insert id="addUser" useGeneratedKeys= ...
 - Bentley二次开发中的,沿曲线构造拉伸实体问题
			
引用文件:Bentley.Interop.MicroStationDGN 本人开发过程中遇到问题: 创建多个线段及弧线,通过自动创建复杂链获得,沿曲线构造拉伸实体的Path参数,拉伸曲线路径首尾特别近 ...
 - web前端知识体系大全【转载】
			
自己总结的web前端知识体系大全[欢迎补充] 1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在 ...
 - java虚拟机规范(se8)——java虚拟机的编译(四)
			
3.12 抛出和处理异常 在程序中使用throw关键字来抛出异常.编译结果很简单. void cantBeZero(int i) throws TestExc { if (i == 0) { thro ...