bzoj 4653: [Noi2016]区间

Posted ws_ccd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4653: [Noi2016]区间相关的知识,希望对你有一定的参考价值。

额,是不是一到了晚上IQ就--;

这个题一开始完全没有思路。(貌似脑子就没动一下)

%了一下题解。

大概是决策是有单调性的,因为要去区间长度差最小,所以接排个序,然后扫描右端点,找出满足有点被覆盖m次的最右的左端点就好。

然后判断是不是有覆盖m个点的用线段树维护一下。

(23333,吐槽,为什么离散化二分的时候,把左端点搞成0,右端点搞成L就会RE??excuse me?!!)

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define inf 0x7fffffff
 4 using namespace std;
 5 inline int ra()
 6 {
 7     int x=0,f=1; char ch=getchar();
 8     while (ch<0 || ch>9) {if (ch==-) f=-1; ch=getchar();}
 9     while (ch>=0 && ch<=9) {x=x*10+ch-0; ch=getchar();}
10     return x*f;
11 }
12 
13 const int maxn=500005;
14 
15 struct seg{int l,r,tag,mx;}t[maxn<<3];
16 struct data{int x,y,len;}a[maxn];
17 
18 int L,n,m,b[maxn<<1],tot,ans=inf;
19 bool cmp_len(data a, data b){return a.len<b.len;}
20 int find(int x)
21 {
22     int l=1,r=L-1;
23     while (l<=r)
24     {
25         int mid=l+r>>1;
26         if (b[mid]==x) return mid;
27         else if (b[mid]<x) l=mid+1;
28         else r=mid-1;
29     }
30 }
31 void build(int k, int l, int r)
32 {
33     t[k].l=l; t[k].r=r;
34     if (l==r) return;
35     int mid=l+r>>1;
36     build(k<<1,l,mid); build(k<<1|1,mid+1,r);
37 }
38 void pushdown(int k)
39 {
40     int tmp=t[k].tag; t[k].tag=0;
41     t[k<<1].tag+=tmp; t[k<<1|1].tag+=tmp;
42     t[k<<1].mx+=tmp; t[k<<1|1].mx+=tmp;
43 }
44 void update(int k) {t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);}
45 void change(int k, int x, int y, int val)
46 {
47     int l=t[k].l,r=t[k].r;
48     if (x==l && y==r)
49     {
50         t[k].tag+=val; t[k].mx+=val;
51         return;
52     }
53     if (t[k].tag) pushdown(k);
54     int mid=l+r>>1;
55     if (y<=mid) change(k<<1,x,y,val);
56     else if (x>mid) change(k<<1|1,x,y,val);
57     else change(k<<1,x,mid,val),change(k<<1|1,mid+1,y,val);
58     update(k); 
59 }
60 int main()
61 {
62 //    freopen("bzoj4653_data.in","r",stdin);
63 //    freopen("bzoj4653_data.out","w",stdout);
64     n=ra(); m=ra();
65     if (!m) {puts("0");return 0;}
66     for (int i=1; i<=n; i++) 
67     {
68         a[i].x=ra(),a[i].y=ra(),a[i].len=a[i].y-a[i].x;
69         b[++tot]=a[i].x; b[++tot]=a[i].y;
70     }
71     sort(a+1,a+n+1,cmp_len); sort(b+1,b+tot+1);
72     L=unique(b+1,b+tot+1)-b; 
73     for (int i=1; i<=n; i++) a[i].x=find(a[i].x),a[i].y=find(a[i].y);
74     int now=1; build(1,1,L);
75     for (int i=1; i<=n; i++)
76     {
77         change(1,a[i].x,a[i].y,1);
78         while (t[1].mx>=m)
79         {
80             ans=min(ans,a[i].len-a[now].len);
81             change(1,a[now].x,a[now].y,-1);
82             now++;
83         }
84     }
85     printf("%d\n",ans==inf?-1:ans);
86     return 0;
87 }

 

以上是关于bzoj 4653: [Noi2016]区间的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ4653][Noi2016]区间

bzoj 4653: [Noi2016]区间

BZOJ4653: [Noi2016]区间

bzoj4653 [Noi2016]区间

BZOJ4653[Noi2016]区间 双指针法+线段树

[BZOJ]4653: [Noi2016]区间