2528 線段樹 + 離散化
阿新 • • 發佈:2019-02-18
#include<iostream> #include<cstdio> #include<algorithm> #include<set> using namespace std; const int maxn = 1e5; int rr[maxn+10]; int ll[maxn+10]; int p[maxn+10]; struct Nod{ int va,q; }nod[(maxn << 2) + 10]; int bs(int l,int r,int k){ int ans = -1,mid; while(l <= r){ mid = l + (r-l)/2; if(p[mid] >= k){ ans = mid; r = mid-1; }else l = mid+1; } if(p[ans] == k) return ans; else return -1; } void build(int o,int l ,int r){ nod[o].va = nod[o].q = 0; if(l == r) return ; int mid = l + (r - l)/2; build(o << 1,l,mid); build(o <<1|1,mid+1,r); } void pushdown(int o){ if(nod[o].q){ nod[o << 1].q = nod[o <<1|1].q = nod[o].q; nod[o << 1].va = nod[o <<1|1].va = nod[o].q; nod[o].q = 0; } } void updata(int o,int l,int r,int L,int R,int k){ if(L <= l && r <= R){ nod[o].va = nod[o].q = k; return ; } pushdown(o); int mid = l + (r - l)/2; if(L <= mid) updata(o << 1,l,mid,L,R,k); if(R > mid) updata(o << 1|1,mid+1,r,L,R,k); } int ans; void query(int o,int l,int r,int p){ if(l == r && l == p){ ans = nod[o].va; return ; } pushdown(o); int mid = l + (r - l)/2; if(p <= mid) query(o << 1,l,mid,p); if(p > mid) query(o << 1|1,mid+1,r,p); } int main(){ int T;scanf("%d",&T); while(T --){ set<int> S; int sz = 0; int n;scanf("%d",&n);int t = 0; for(int i = 1;i <= n;++i){ scanf("%d%d",&rr[i],&ll[i]); S.insert(rr[i]);if(S.size() > sz) { sz = S.size();p[++t] = rr[i]; } S.insert(ll[i]);if(S.size() > sz) { sz = S.size();p[++t] = ll[i]; } } sort(p+1,p+1+t); for(int i = 1;i <= n;++i){ rr[i] = bs(1,t,rr[i]); ll[i] = bs(1,t,ll[i]); } build(1,1,t); for(int i = 1;i <= n;++i){ updata(1,1,t,rr[i],ll[i],i); } set<int> S1; sz = 0; for(int i = 1;i <= t;++i){ query(1,1,t,i); S1.insert(ans); } printf("%d\n",S1.size()); } return 0; }