[HAOI2014] 贴海报

因为后贴的海报可以覆盖前面已贴的海报或部分海报,所以我们倒序贴海报

一个海报可以被看见,只有在他所在的区间内至少有一格没有被贴上海报

我们可以将贴海报的过程想象成在一段区间上染色,当我们考虑一个新海报时,我们只需要判断他所在区间内有没有还没被染上色的格子,然后将他所在区间全部染上色,这个过程是可以用线段树优化

对于线段树的每一个节点,我们记录他有没有被完全染上色,查询时当查询到一个被完全染上色的节点后直接返回就行,而修改时就正常区间修改就行

注意:区间范围过大需要离散化

AC代码

using namespace std;
#define ll long long
#define MAXN 4010
#define bl bool 
inline ll read(){
	ll x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
struct node{
	bl tag[MAXN*4];
	ll l[MAXN*4],r[MAXN*4];
	void push_up(ll now){
		tag[now]=tag[now*2]&tag[now*2+1];
	}
	void build(ll now,ll lz,ll rz){
		l[now]=lz,r[now]=rz;
		if(lz==rz)return;
		ll mid=(lz+rz)/2;
		build(now*2,lz,mid);
		build(now*2+1,mid+1,rz);
	}
	void ad(ll now,ll lz,ll rz){
		if(tag[now])return;
		if(l[now]>=lz&&r[now]<=rz){
			tag[now]=1;
			return;
		}
		ll mid=(l[now]+r[now])/2;
		if(lz<=mid)ad(now*2,lz,rz);
		if(rz>mid)ad(now*2+1,lz,rz);
		push_up(now);
	}
	bl re(ll now,ll lz,ll rz){
		if(tag[now])return 0;
		if(l[now]>=lz&&r[now]<=rz)return 1;
		ll mid=(l[now]+r[now])/2,ans=0;
		if(lz<=mid)ans|=re(now*2,lz,rz);
		if(rz>mid)ans|=re(now*2+1,lz,rz);
		return ans;
	}
};
bool cmp(ll a,ll b){
	return a>b;
}
struct node_has{
	ll pre[MAXN];
	ll siz;
	void insert(ll x){
		pre[++siz]=x;
	}
	void mk(){
		sort(pre+1,pre+1+siz);
		ll _siz=siz;
		for(ll i=1;i<=_siz;i++){
			if(pre[i]==pre[i+1]){
				pre[i]=0;
				siz--;
			}
		}
		sort(pre+1,pre+1+_siz,cmp);
		sort(pre+1,pre+1+siz);
	}
	ll find(ll x){
		ll l=1,r=siz;
		while(l<r){
			ll mid=(l+r+1)/2;
			if(pre[mid]<=x)l=mid;
			else r=mid-1;
		}
		return l;
	}
}has;
ll n,m,ans;
ll l[MAXN],r[MAXN];
node tr;
int main(){
	n=read(),m=read();
//	tr.build(1,1,n);
	for(ll i=1;i<=m;i++){
	 	l[i]=read(),r[i]=read();
	 	has.insert(l[i]),has.insert(r[i]);
	 	has.insert(r[i]+1),has.insert(l[i]-1);
	}
	has.mk();
	tr.build(1,1,has.siz);
	for(ll i=m;i;i--){
		l[i]=has.find(l[i]),r[i]=has.find(r[i]);
//		cout<<l[i]<<" "<<r[i]<<endl;
		if(tr.re(1,l[i],r[i]))ans++;
		tr.ad(1,l[i],r[i]);
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2024-11-24 16:26  flyfreemrn  阅读(19)  评论(0)    收藏  举报