[HAOI2011]problem a

[HAOI2011]problem a

思考一下:转化条件则一个人在 \([a + 1,n - b]\)排名中,且这些人分数都一样。

那么就是若干个区间选择不交集合的问题。

// Problem: P2519 [HAOI2011]problem a
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2519
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 1000005

ll n,cnt,tot;

struct seg{
	ll l,r,v;
}e[N],p[N];

ll f[N];

bool operator < (seg a,seg b){
	if(a.r != b.r)
	return a.r < b.r;
	else
	return a.l < b.l;
}

#define mid ((l + r) >> 1)

inline ll find(int u){
	ll l = 1,r = u - 1;
	while(l + 1 < r){
		if(p[mid].r < p[u].l)
		l = mid;
		else
		r = mid;
	}
	while(p[l + 1].r < p[u].l)
	++l;
	return l;
}

int main(){
	scanf("%lld",&n);
	for(int i = 1;i <= n;++i){
		ll l,r;
		scanf("%lld%lld",&l,&r);
		ll a = l + 1,b = n - r;
		if(a <= b && l + r < n)
		e[++cnt].l = a,e[cnt].r = b;
	}
	std::sort(e + 1,e + cnt + 1);
	ll last = 1;
	// for(int i = 1;i <= cnt;++i)
	// std::cout<<e[i].l<<" "<<e[i].r<<std::endl;
	for(int i = 1;i <= cnt + 1;++i){
		if(e[last].l != e[i].l || e[last].r != e[i].r)
		p[++tot].l = e[last].l,p[tot].r = e[last].r,p[tot].v = i - last,last = i;
	}
	for(int i = 1;i <= tot;++i)
	p[tot].v = std::min(p[tot].v,1ll * p[tot].r - p[tot].l + 1);
	// for(int i = 1;i <= tot;++i)
	// std::cout<<p[i].l<<" "<<p[i].r<<" "<<p[i].v<<std::endl;
	// find(2);
	f[1] = p[1].v;
	for(int i = 2;i <= tot;++i){
		ll k = find(i);
		f[i] = std::max(f[i - 1],f[k] + p[i].v);
	}
	std::cout<<n - f[tot]<<std::endl;
}
posted @ 2021-07-16 15:03  fhq_treap  阅读(30)  评论(0编辑  收藏  举报