登 录
和poj2777涂颜色一样的思路。
线段树:1,一般是遇到(l==r)时,return;2,mid+1属于右子树。
#include<iostream> #include<string> #include<cstdio> #include<algorithm> using namespace std; #define maxn 100005 bool vis[maxn]; class node { public: int l,r; int step; }; class point { public: int a,b; }; point pro[maxn]; int INDEX[maxn*2],cnt; node tree[maxn*4]; int n; void build(int l,int r,int index) { tree[index].l =l;tree[index].r =r; tree[index].step =0; if(l==r) return; int mid=(l+r)>>1; build(l,mid,index*2); build(mid+1,r,index*2+1); } void insert(int l,int r,int step,int index)//插入一段区间 { if(l==tree[index].l &&r==tree[index]. r) { tree[index].step =step; return ; } if(tree[index].step !=0&&tree[index].step!=step) { tree[index*2].step =tree[index].step ;//往后更新 这是核心 tree[index*2+1].step =tree[index].step ; tree[index].step =0; } int mid=(tree[index].l +tree[index].r)>>1; if(l>mid) insert(l,r,step,index*2+1); else if(r<=mid) insert(l,r,step,index*2); else { insert(l,mid,step,index*2); insert(mid+1,r,step,index*2+1); } } void search(int index)//寻找还有多少颜色存在 { if(tree[index].step !=0) { vis[tree[index].step ]=1; return ; } int mid=(tree[index].l +tree[index].r )>>1; search(index*2); search(index*2+1); } int getindex(int a)//二分查找对应的INDEX { int l=0,r=cnt-1; while(l<r) { int mid=(l+r)>>1; if(a<=INDEX[mid]) r=mid; else l=mid+1; } return r; } int main() { int t,i,a,b; cin>>t; while(t--) { cin>>n; for(i=0;i<n;i++) { cin>>a>>b; pro[i].a=a;pro[i].b=b; INDEX[i*2]=a;INDEX[i*2+1]=b; } sort(INDEX,INDEX+2*n); cnt=0; for(i=1;i<n*2;i++) { if(INDEX[i]!=INDEX[i-1]) INDEX[cnt++]=INDEX[i-1]; } INDEX[cnt++]=INDEX[2*n-1]; build(0,cnt-1,1); for(i=0;i<n;i++) { insert(getindex(pro[i].a),getindex(pro[i].b ),i+1,1); } memset(vis,0,sizeof(vis)); search(1); int ans=0; for(i=1;i<=n;i++) if(vis[i]) ans++; cout<<ans<<endl; } return 0; }
抱歉!评论已关闭.