1103四校聯考--表格
阿新 • • 發佈:2018-12-12
題解如下
看完上面的題解如果還不懂的話,我就藉著上面的思路講講自己的理解吧
區間修改跟往常一樣
對於更新來說,這一次集合中的最大數大於左右子樹的最大值
那麼當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 */