标签:
首先将区间按长度排序后离散化端点(这里的“长度”指的是离散化之前区间的实际长度)
然后模拟一个队列,区间按排好的顺序依次进入,直到某个点被覆盖了M次。之后依次出队,直到所有点都被覆盖小于M次
修改和询问覆盖次数可以用线段树实现
1 //C++11 code 2 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 7 const int maxN=500005; 8 const int inf=0x7f7f7f7f; 9 10 struct Range 11 { 12 int left,right; 13 int len; 14 void assign(int l,int r) { left=l; right=r; len=r-l; } 15 }; 16 17 struct SegTree 18 { 19 struct Node 20 { 21 int val=0; //max-val 22 int tag=0; 23 int total() { return val+tag; } 24 }; 25 Node node[maxN<<2]; 26 int size; 27 int _val; 28 29 void update(int cur,int right) 30 { 31 node[cur].val = std::max(node[cur+1].total(),node[right].total()); 32 } 33 void add(int L,int R,int val) 34 { 35 _val=val; 36 __add(0,L,R+1,0,size); 37 } 38 void __add(int cur,int rL,int rR,int nL,int nR) 39 { 40 if(rL<=nL && rR>=nR) 41 { 42 node[cur].tag+=_val; 43 return; 44 } 45 int mid=(nL+nR)>>1; 46 int right=cur+((mid-nL)<<1); 47 if(rL<mid) __add(cur+1,rL,rR,nL,mid); 48 if(rR>mid) __add(right,rL,rR,mid,nR); 49 update(cur,right); 50 } 51 int askAll() { return node[0].total(); } 52 }; 53 54 Range rg[maxN]; 55 SegTree segt; 56 57 int N,M; 58 int buf[maxN<<1]; 59 int valNum; 60 61 void input() 62 { 63 scanf("%d%d",&N,&M); 64 int tl,tr; 65 for(int i=0;i<N;i++) 66 { 67 scanf("%d%d",&tl,&tr); 68 buf[i<<1]=tl; 69 buf[(i<<1)+1]=tr; 70 rg[i].assign(tl,tr); 71 } 72 } 73 74 void discretize() 75 { 76 std::sort(buf,buf+(N<<1)); 77 valNum=std::unique(buf,buf+(N<<1))-buf; 78 for(int i=0;i<N;i++) 79 { 80 rg[i].left=std::lower_bound(buf,buf+valNum,rg[i].left)-buf; 81 rg[i].right=std::lower_bound(buf,buf+valNum,rg[i].right)-buf; 82 } 83 } 84 85 int solve() 86 { 87 int res=inf; 88 auto cmpIdx=[](const Range& A,const Range& B)->bool { return A.len<B.len; }; 89 std::sort(rg,rg+N,cmpIdx); 90 discretize(); 91 segt.size=valNum; 92 int head=-1,tail=-1; 93 while(1) 94 { 95 while((++head)<N && segt.askAll()<M) 96 segt.add(rg[head].left,rg[head].right,1); 97 if(segt.askAll()<M) break; 98 else --head; 99 while(segt.askAll()==M) 100 { 101 ++tail; 102 res=std::min(res,rg[head].len-rg[tail].len); 103 segt.add(rg[tail].left,rg[tail].right,-1); 104 } 105 } 106 return (res==inf)?-1:res; 107 } 108 109 int main() 110 { 111 input(); 112 printf("%d\n",solve()); 113 return 0; 114 }
标签:
原文地址:http://www.cnblogs.com/Onlynagesha/p/5727249.html