• [NOI2016] 区间


    不是很会做。
    大概是以前没有见过这种trick的原因。
    自己想到了线段树维护出现点数,但是不会统计答案。

    先分析一些东西:
    首先因为只有(m)个区间要被选,且答案贡献为(max - min),可以考虑尺取。
    感觉知道这个核心(trick)就能做了。
    从小到大加入,线段树随便维护一下。

    [NOI2016] 区间
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    #define N 500005
    
    struct P{ll l,r,len;}e[N];
    
    inline bool operator < (P a,P b){
    	return a.len < b.len;
    }
    
    ll b[N << 2];
    ll n,m;
    
    int ma[N << 3],lazy[N << 3];
    
    #define l(x) (x << 1)
    #define r(x) (x << 1 | 1)
    #define mid ((l + r) >> 1)
    
    inline void up(int u){
    	ma[u] = std::max(ma[l(u)],ma[r(u)]);
    }
    
    inline void down(int u){
    	ma[l(u)] += lazy[u];
    	ma[r(u)] += lazy[u];
    	lazy[l(u)] += lazy[u];
    	lazy[r(u)] += lazy[u];
    	lazy[u] = 0;
    }
    
    inline void add(int u,int l,int r,int tl,int tr,int p){
    //	std::cout<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<" "<<p<<std::endl;		
    	if(tl <= l && r <= tr){
    		ma[u] += p;
    		lazy[u] += p;
    //		std::cout<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<ma[u]<<" "<<p<<std::endl;		
    		return ;
    	}
    	down(u);
    	if(tl <= mid)
    	add(l(u),l,mid,tl,tr,p);
    	if(tr > mid)
    	add(r(u),mid + 1,r,tl,tr,p);
    	up(u);
    //	std::cout<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<ma[u]<<" "<<p<<std::endl;
    }
    
    ll ans = 0x3f3f3f3f;
    
    int main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i = 1;i <= n;++i){
    		scanf("%lld%lld",&e[i].l,&e[i].r);
    		e[i].len = (e[i].r - e[i].l);
    //		b[++b[0]] = e[i].l - 1;
    		b[++b[0]] = e[i].l;
    		b[++b[0]] = e[i].r;
    //		b[++b[0]] = e[i].r + 1;
    	}
    	std::sort(b + 1,b + b[0] + 1);
    	std::sort(e + 1,e + n + 1);
    	b[0] = std::unique(b + 1,b + b[0] + 1) - b - 1;
    	ll l = 1;
    	ll r = 1;
    	e[n + 1].len = 0x3f3f3f3f; 
    //	for(int i = 1;i <= n;++i){
    ////		ll li = std::lower_bound(b + 1,b + b[0] + 1,e[i].l)- b;
    ////		ll ri = std::lower_bound(b + 1,b + b[0] + 1,e[i].r)- b;
    //		std::cout<<e[i].l<<" "<<e[i].r<<" "<<e[i].len<<" "<<std::endl;
    //	}
    	ll li = std::lower_bound(b + 1,b + b[0] + 1,e[1].l) - b;
    	ll ri = std::lower_bound(b + 1,b + b[0] + 1,e[1].r) - b;
    	add(1,1,b[0],li,ri,1);
    	while(l <= n && r <= n){
    		while(ma[1] >= m){
    			ll li = std::lower_bound(b + 1,b + b[0] + 1,e[l].l) - b;
    			ll ri = std::lower_bound(b + 1,b + b[0] + 1,e[l].r) - b;
    			add(1,1,b[0],li,ri,-1);
    //			std::cout<<l<<" "<<r<<" "<<e[r].len<<" "<<e[l].len<<" "<<ma[1]<<std::endl;
    			ans = std::min(e[r].len - e[l].len,ans);			
    			++l;
    		}
    		while(ma[1] < m){
    			++r;
    			if(r > n)
    			break;
    			ll li = std::lower_bound(b + 1,b + b[0] + 1,e[r].l) - b;
    			ll ri = std::lower_bound(b + 1,b + b[0] + 1,e[r].r) - b;
    			add(1,1,b[0],li,ri,1);
    		}
    	}
    	if(ans < 0x3f3f3f3f)
    	std::cout<<ans<<std::endl;
    	else
    	puts("-1");
    }
    
  • 相关阅读:
    MySQL中各数据类型的取值范围
    解决方法:访问接口 "SQLNCLI10" 的架构行集 "DBSCHEMA_TABLES_INFO"。该访问接口支持该接口
    mysql中数据类型N
    有点想鸟
    了解 Microsoft Access 安全性
    用Delphi编写ASP的ActiveX
    用Delphi制作DLL的方法
    功自诚在,利从义来
    手把手教delphi:写你的dll文件--因为想帮兄弟写个dll,把原来压箱底的东东翻出来,快作完了,但要测试先
    还是有一点点累
  • 原文地址:https://www.cnblogs.com/dixiao/p/14891077.html
Copyright © 2020-2023  润新知