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 }