题解如下
看完上面的题解如果还不懂的话,我就借着上面的思路讲讲自己的理解吧
区间修改跟往常一样
对于更新来说,这一次集合中的最大数大于左右子树的最大值
那么当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
*/