1. 程式人生 > >1103四校聯考--表格

1103四校聯考--表格

題解如下

看完上面的題解如果還不懂的話,我就藉著上面的思路講講自己的理解吧

區間修改跟往常一樣

對於更新來說,這一次集合中的最大數大於左右子樹的最大值

那麼當max不小於min的時候,max就是這個數了

為什麼有這個限制條件呢?因為如果之前某個數被選過了,就會導致min比較大

而max還沒有被更新過,現在就可能比min更小,而這顯然是不合法的

另外還要注意離散化的時候一定要把x軸區間右端點+1的位置也給放進去

如果直接放入下一次的情況統計,會讓狀態減少,沒有統計剛好結束這個區間時的狀態

貼程式碼

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<vector>
#include<set>
#define RG register
using namespace std;
int ans,n,a[800005],b[800005],c[800005],d[800005],que2[800005];
int que1[800005],tot,pd[800005],ll[800005],rr[800005],tot1,tot2;
struct node
{
	node *ls,*rs;
	int mina,maxa;
	set<int> s;
}pool[1600005],*root,*tail=pool;
struct lql
{
	int id,l,r,flag;
	lql(int ii=0,int ll=0,int rr=0,int ff=0){id=ii;l=ll;r=rr;flag=ff;}
};
vector <lql> vec[800005];
int maxn(int x,int y)
{
	if(x>y) return x;
	return y;
}
int minn(int x,int y)
{
	if(x<y) return x;
	return y;
}
void build(node *&nd,int l,int r)
{
	nd=tail++;
	nd->mina=nd->maxa=-1;
	if(l==r)
	{
		return;
	}
	int mid=(l+r)>>1;
	build(nd->ls,l,mid);
	build(nd->rs,mid+1,r);
}
void update(node *&nd)
{
	if(nd->ls==NULL&&nd->rs==NULL)
	{
		if(nd->s.empty()) nd->maxa=nd->mina=-1;
		else 
		{
			nd->maxa=*nd->s.rbegin();
			nd->mina=*nd->s.rbegin();
			if(pd[nd->maxa])
			nd->maxa=-1;
		}
		return;
	}
	nd->mina=minn(nd->ls->mina,nd->rs->mina);
	nd->maxa=maxn(nd->ls->maxa,nd->rs->maxa);
	if(nd->s.empty()) return;
	int now=*nd->s.rbegin();
	nd->mina=maxn(nd->mina,now);
	if(nd->maxa<now)
	{
		if(pd[now])
		{
			nd->maxa=-1;
		}
		else 
		{
			if(now<nd->mina) nd->maxa=-1;
			else nd->maxa=now;
		}
	}
}
void modify(node *&nd,int l,int r,int L,int R,int delta,int kind)
{
	if(l>=L&&r<=R)
	{
		if(kind==1)
		nd->s.insert(delta);
		else nd->s.erase(delta);
		update(nd);
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=L) modify(nd->ls,l,mid,L,R,delta,kind);
	if(mid<R) modify(nd->rs,mid+1,r,L,R,delta,kind);
	update(nd);
}
int read()
{
	char c;
	int x;
	for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
	if(c=='-')
	{
		x=0;
		for(c=getchar();c>='0'&&c<='9';c=getchar())
		x=x*10+c-'0';
		return -x;
	}
	else 
	{
		x=c-'0';
		for(c=getchar();c>='0'&&c<='9';c=getchar())
		x=x*10+c-'0';
		return x;
	}
}
void up(node *nd,int l,int r,int L,int R)
{
	if(l>=L&&r<=R)
	{
		update(nd);
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=L) up(nd->ls,l,mid,L,R);
	if(mid<R) up(nd->rs,mid+1,r,L,R);
	update(nd);
}
int main()
{
	freopen("excel.in","r",stdin);
	freopen("excel.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		a[i]=read();b[i]=read();c[i]=read();d[i]=read();
		c[i]--;
		d[i]--;
		que1[++tot]=a[i];
		que2[tot]=b[i];
		que1[++tot]=c[i];
		que2[tot]=d[i];
		que1[++tot]=a[i]+1;
		que2[tot]=b[i]+1;
		que1[++tot]=c[i]+1;
		que2[tot]=d[i]+1;
	}
	sort(que1+1,que1+tot+1);
	sort(que2+1,que2+tot+1);
	RG int now=unique(que1+1,que1+tot+1)-que1-1;
	tot1=now;
	now=unique(que2+1,que2+tot+1)-que2-1;
	tot2=now;
	ans=1;
	for(RG int i=1;i<=n;i++)
	{
		a[i]=lower_bound(que1+1,que1+tot1+1,a[i])-que1;
		b[i]=lower_bound(que2+1,que2+tot2+1,b[i])-que2;
		c[i]=lower_bound(que1+1,que1+tot1+1,c[i])-que1;
		d[i]=lower_bound(que2+1,que2+tot2+1,d[i])-que2;
	} 
	for(int i=1;i<=n;i++)
	{
		vec[a[i]].push_back(lql(i,b[i],d[i],1));
		vec[c[i]+1].push_back(lql(i,b[i],d[i],-1));
		ll[i]=b[i];
		rr[i]=d[i];
	}
	build(root,1,tot2);
	for(int i=1;i<=tot1;i++)
	{
		if(vec[i].size())
		{
			for(vector <lql> ::iterator it=vec[i].begin(),ed=vec[i].end();it!=ed;it++)
			{
				modify(root,1,tot2,it->l,it->r,it->id,it->flag);
			}
		}
		while(root->maxa!=-1)
		{
			pd[root->maxa]=1;
			ans++;
			up(root,1,tot2,ll[root->maxa],rr[root->maxa]);
		}
	}
	
	cout<<ans;
	return 0;
}
/*
2
1 1 2 2
0 0 4 4
*/