参照HH牛的模板敲的。RE了3次后发现X数组开小了,坑死爹了。
HH牛的博客:http://www.notonlysuccess.com/index.php/segment-tree-complete/
#include <cstdio> #include <algorithm> #include <cstring> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid (l+r)>>1 using namespace std; const int maxn=10000+5; bool hash[maxn]; int X[maxn*4]; int col[maxn<<4]; int li[maxn],ri[maxn]; int cnt; void PushDown(int rt)//更新col到子结点 { if(col[rt]!=-1) { col[rt<<1|1]=col[rt<<1]=col[rt]; col[rt]=-1; } } void query(int l,int r,int rt)//查询区间(l,r)之间线段的染色情况 { if(col[rt]!=-1) { if(!hash[col[rt]]) cnt++; hash[col[rt]]=true; return ; } if(l==r) return ; int m=mid; query(lson); query(rson); } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { col[rt]=c; return ; } PushDown(rt); int m=mid; if(m>=L) update(L,R,c,lson); if(m<R) update(L,R,c,rson); } int Bin(int key,int n,int X[])//二分查找+离散化 { int l=0,r=n-1; while(l<=r) { int m=mid; if(X[m]==key) return m; if(X[m]>key) r=m-1; else l=m+1; } return -1; } int main() { int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); int nn=0; for(int i=0;i<n;i++)//所有出现的点存入数组 { scanf("%d%d",&li[i],&ri[i]); X[nn++]=li[i]; X[nn++]=ri[i]; } sort(X,X+nn); int m=1; for(int i=1;i<nn;i++)//清除重复的点 if(X[i]!=X[i-1]) X[m++]=X[i]; for(int i=m-1;i>0;i--)//防止离散化出现问题,详见HH牛的解释 if(X[i]!=X[i-1]+1) X[m++]=X[i-1]+1; sort(X,X+m); memset(col,-1,sizeof(col)); for(int i=0;i<n;i++) { int l=Bin(li[i],m,X); int r=Bin(ri[i],m,X); update(l,r,i,0,m,1); } memset(hash,false,sizeof(hash)); cnt=0; query(0,m,1); printf("%d\n",cnt); } return 0; }