BZOJ 4653: [Noi2016] discretization interval + + monotonic segment tree pointer maintenance

title

BZOJ 4653

LUOGU 1712

Description

On the number line with a \ (N \) th closed interval \ ([L_1, R_1], [L_2, R_2], ..., [L_n, R_n] \) . Now from selected \ (M \) intervals, making it a \ (M \) intervals together comprise at least one location. In other words, the presence of such a \ (X \) , such that for each selected interval \ ([L_i, r_i] \) , are \ (L_i \ leqslant X \ leqslant r_i \) .

For the selection of a legitimate program, its cost minus the selected minimum interval length is selected longest interval length. Interval \ ([l_i, r_i] \ ) is defined as the length \ (r_i-L_i \) , i.e. it is equal to the value of the value obtained by subtracting the right point of the left point.

All programs seek legal minimum cost. If a legitimate program does not exist, output \ (--1 \) .

Input

The first line contains two positive integers \ (N, M \) separated by a space, meaning as described above. Ensure \ (1 \ leqslant M \ leqslant N \)

Next \ (N \) rows, each row represents a section, comprising two integers separated by a space \ (L_i \) and \ (r_i \) for the left and right end sections.

\(N\leqslant 500000,M\leqslant 200000,0\leqslant l_i\leqslant r_i\leqslant 10^9\)

Output

Only one line containing a positive integer that is the minimum cost.

Sample Input

6 3
3 5
1 2
3 4
2 2
1 5
1 4

Sample Output

2

analysis

Again feeling a little run into network flows 24 questions, but a closer look, there is not the same (skip this passage).

Violence again openly consider how to write, make sure all sections of ordering it, then enumerate a range as the left point, right point as an interval, then the answer is in the big interval to election.

There is a transformation of thinking:

There \ (M \) intervals together comprise a position equivalent have been through this period of range \ (M \) time points.

So practice came out, we all corresponding period of the interval of this paragraph of the number of passes are a plus, just look at this last paragraph is whether there is a through \ (M \) times the point, once it exists instructions, we will be able to find them \ (M \) intervals to meet the subject requirements, you can use the right end of the interval length - the length of the interval left endpoint to update the answer.

Then segment tree to maintain, the complexity is \ (O (N ^ 2 \ log N) \) .

It is not difficult (Difficult) Found that: the right end point of fact, not monotonous, not fall, so there is no need to enumerate the right point, just use the pointer has been a monotonous sweep back on it, the complexity becomes \ (O (N \ log N ) \) .

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10,inf=0x7fffffff;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x)
{
    if (!x) *fe++=48;
    if (x<0) *fe++='-', x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) *fe++=ch[num--];
    *fe++='\n';
}

int tree[maxn<<2],atag[maxn<<2];//由于一个区间有两个点,所以最坏情况要开八倍数组,maxn已经乘2了
inline void pushdown(int now,int l,int r)
{
    if (l==r) { atag[now]=0; return ; }
    atag[now<<1]+=atag[now], atag[now<<1|1]+=atag[now];
    tree[now<<1]+=atag[now], tree[now<<1|1]+=atag[now];
    atag[now]=0;
}

inline void Change(int now,int l,int r,int tl,int tr,int k)
{
    if (tl<=l && r<=tr)
    {
        tree[now]+=k, atag[now]+=k;
        return ;
    }
    if (atag[now]) pushdown(now,l,r);
    int mid=(l+r)>>1;
    if (tl<=mid) Change(now<<1,l,mid,tl,tr,k);
    if (tr>mid) Change(now<<1|1,mid+1,r,tl,tr,k);
    tree[now]=max(tree[now<<1],tree[now<<1|1]);
}

struct Orz{int l,r,i;}q[maxn];
inline bool cmp(Orz a,Orz b)
{
    return a.i<b.i;
}

int c[maxn<<1],cnt;
int main()
{
    int n,m;read(n);read(m);
    for (int i=1; i<=n; ++i)
    {
        read(q[i].l),read(q[i].r);
        q[i].i=q[i].r-q[i].l;
        c[++cnt]=q[i].l,c[++cnt]=q[i].r;
    }
    sort(c+1,c+cnt+1);
    cnt=unique(c+1,c+cnt+1)-c-1;
    for (int i=1; i<=n; ++i) q[i].l=lower_bound(c+1,c+cnt+1,q[i].l)-c,q[i].r=lower_bound(c+1,c+cnt+1,q[i].r)-c;//找到区间i可修改的范围
    sort(q+1,q+n+1,cmp);
    int now=0,ans=inf;
    for (int i=1; i<=n; ++i)
    {
        while (tree[1]<m && now<n) ++now,Change(1,1,cnt,q[now].l,q[now].r,1);
        if (tree[1]==m) ans=min(ans,q[now].i-q[i].i);
        Change(1,1,cnt,q[i].l,q[i].r,-1);
    }
    write(ans==inf?-1:ans);
    flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11350545.html