POJ - 2528 Mayor's posters
阿新 • • 發佈:2020-12-17
題目大意
有 T 組資料,每組資料有一個 N 表示有 N 個人一次貼海報
然後 N 對 \(L_i\ R_i\) 表示一張海報的範圍,問最後能看見多少張海報
資料範圍:\(n\le 10000\ \ L_i\ R_i\le 10^7\)
題解
(開始英語不好看不懂題折騰了半天)
可以看出是線段樹區改裸題
但是\(L_i\ R_i\le 10^7\) ,直接改會\(TLE\)
所以要離散化。
於是 \(Sort+Unique+LowerBound\)(這題肯定要把\(L_i\ \ R_i\)一起離散)
但是要注意:設離散化陣列為\(X\)但存在\(X_i-X_{i-1}>1\)時,要加入一個元素\(X_{new}\)
為了方便可以先插入到最後然後排序。線段樹部分不做闡述
標
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char buf[100000],*L=buf,*R=buf; inline char Gc() { return L==R&&(R=(L=buf)+fread(buf,1,100000,stdin),L==R)?EOF:*L++; } inline int Rd() { register int o=0; char c=Gc(); for(;c<'0'||c>'9';c=Gc()) ; for(;c>'/'&&c<':';c=Gc())o=(o<<1)+(o<<3)+(c^48); return o; } void Write(int o) { if(o>9)Write(o/10); putchar(o%10+48); } int T,n,tot,cnt,ans,l[20005],r[20005],x[80005]; int cl[320005],vis[320005]; inline void Dw(int rt) { if(!cl[rt])return; cl[rt<<1]=cl[rt<<1|1]=cl[rt]; cl[rt]=0; } void Chan(int ql,int qr,int vl,int l,int r,int rt) { if(ql<=l && r<=qr) { cl[rt]=vl; return; } Dw(rt); register int mid=l+r>>1; if(ql<=mid)Chan(ql,qr,vl,l,mid,rt<<1); if(qr>mid)Chan(ql,qr,vl,mid+1,r,rt<<1|1); } void Query(int l,int r,int rt) { if(cl[rt]) { if(!vis[cl[rt]]) ++ans,vis[cl[rt]]=1; return; } if(l==r)return; register int mid=l+r>>1; Query(l,mid,rt<<1); Query(mid+1,r,rt<<1|1); } int main() { T=Rd(); while(T--) { n=Rd(),tot=ans=0; memset(vis,0,sizeof(vis)); memset(cl,0,sizeof(cl)); for(int i=1;i<=n;i++) { l[i]=Rd(),r[i]=Rd(); x[++tot]=l[i],x[++tot]=r[i]; } sort(x+1,x+tot+1); cnt=unique(x+1,x+tot+1)-x-1; int ttt=cnt; for(int i=2;i<=ttt;i++) if(x[i]-x[i-1]>1)x[++cnt]=x[i-1]+1; sort(x+1,x+cnt+1); for(int i=1,rx,ry;i<=n;i++) { rx=lower_bound(x+1,x+cnt+1,l[i])-x; ry=lower_bound(x+1,x+cnt+1,r[i])-x; Chan(rx,ry,i,1,cnt,1); } Query(1,cnt,1); Write(ans); putchar(10); } }