您的位置:首页 > 其它

BZOJ4653: [Noi2016]区间

2016-09-18 14:08 218 查看
传送门

UOJ上卡掉一个点,COGS上卡掉两个点..弃疗,不改了,反正BZOJ上过啦hhh

先把区间按长度递增排序。然后每次用线段树维护区间最大覆盖次数,用一个指针随便扫扫就行了。

//NOI 2016 D2T1
//by Cydiater
//2016.9.18
#pragma GCC optimize("O2")
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n)        for(INT i=j;i<=n;i++)
#define down(i,j,n)        for(INT i=j;i>=n;i--)
#define FILE "interval"
#define INT unsigned int
const INT MAXN=1e6+5;
const INT oo=0x3f3f3f3f;
map<INT,INT> lable;
inline INT read(){
char ch=getchar();INT x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
INT num[MAXN],N,M,top=0,cnt=0,check=0,x,y,v,ans=oo;
struct Query{
INT st,nd,len;
}q[MAXN];
struct Tree{
INT maxx,delta;
}t[MAXN<<3];
namespace solution{
inline bool cmp(Query a,Query b){return a.len<b.len;}
inline void downit(INT node){
if(t[node].delta==0)return;
t[node<<1].delta+=t[node].delta;t[node<<1|1].delta+=t[node].delta;
t[node<<1].maxx+=t[node].delta;t[node<<1|1].maxx+=t[node].delta;
t[node].delta=0;
}
inline void reload(INT node){t[node].maxx=max(t[node<<1].maxx,t[node<<1|1].maxx);}
void updata(INT leftt,INT rightt,INT root){
downit(root);
if(leftt>y||rightt<x)        return;
if(leftt>=x&&rightt<=y){
t[root].maxx+=v;
t[root].delta+=v;
return;
}
INT mid=(leftt+rightt)>>1;
updata(leftt,mid,root<<1);
updata(mid+1,rightt,root<<1|1);
reload(root);
}
void init(){
N=read();M=read();
up(i,1,N){
q[i].st=read();q[i].nd=read();
num[++top]=q[i].st;num[++top]=q[i].nd;
}
sort(num+1,num+top+1);
up(i,1,top)if(!lable[num[i]])lable[num[i]]=++cnt;
up(i,1,N){
q[i].len=q[i].nd-q[i].st;
q[i].st=lable[q[i].st];
q[i].nd=lable[q[i].nd];
}
sort(q+1,q+N+1,cmp);
}
void slove(){
up(i,1,N){
while(t[1].maxx<M&&check<N){
check++;
x=q[check].st;y=q[check].nd;v=1;
updata(1,cnt,1);
}
if(t[1].maxx>=M)ans=min(ans,q[check].len-q[i].len);
x=q[i].st;y=q[i].nd;v=-1;
updata(1,cnt,1);
}
}
void output(){
if(ans==oo)puts("-1");
else cout<<ans<<endl;
}
}
int main(){
//freopen(FILE".in","r",stdin);
//freopen(FILE".out","w",stdout);
//freopen("input.in","r",stdin);
using namespace solution;
init();
slove();
output();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: