1. 程式人生 > >2528 線段樹 + 離散化

2528 線段樹 + 離散化

#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;
}