这个题目很多网上的解题报告都是错的,
但是交了可以AC。不过我还是仔细检查了一下,最后自己写了二天,很悲剧。
第一次是因为最后的查询区间的(1,k) 写成了(1,n)导致一直检查不出错误,但是从过程中又得到的是正确答案。
第二次是因为离散化,反正是相当的蛋疼。
做线段树已经快一个星期了,感觉自己的决心越来越不够了。
有点失望,害怕……
马上就是区域赛的网络赛了,
虽然自己的实力还欠火候,但是至少这也是自己一个追求……
好了,下面代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define M 50000 //测试过必须要开到5W才能过,不理解为什么。 #define mid (l+r)>>1 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int turn[M<<2],color[M<<2],x[M],y[M],n,k,ans; bool use[M]; int binsch(int p){ int l=0,r=k-1,m; while(l<=r){ m=mid; if(turn[m] == p) return m+1; if(turn[m]<p) l=m+1; else r=m-1; } return -1; } void init(){ int i,j=1,s=0; ans=0; scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d %d",&x[i],&y[i]); turn[s++]=x[i],turn[s++]=y[i]; turn[s++]= (x[i] +y[i])>>1; //离散化过程可能会出现异常,所以在中间添加一个中位数,也可以多添加几个。 //此离散化过了disuss里面的全部数据。 } sort(turn,turn+s); k=1; for(j=1;j<s;j++){ if(turn[j] != turn[j-1]) turn[k++]=turn[j]; } memset(color,0,sizeof(color)); } void pushsub(int rt){ if(color[rt]){ color[rt<<1] = color[rt<<1|1] = color[rt]; color[rt] = 0; } } void change(int c,int L,int R,int l,int r,int rt){ if(L<=l && r<=R){ color[rt] =c; return ; } if(l == r) return ; pushsub(rt); int m = mid; if(L<=m) change(c,L,R,lson); if(m<R) change(c,L,R,rson); } void updata(){ for(int i=0;i<n;i++){ change((i+1),binsch(x[i]),binsch(y[i]),1,k,1); } } void count(int l,int r,int rt){ if(color[rt]&&!use[color[rt]]){ ans++; use[color[rt]]=true; return ; } if(l == r) return ; int m = mid; count(lson); count(rson); } int main(){ int cas; scanf("%d",&cas); while(cas--){ init(); updata(); memset(use,false,sizeof(use)); count(1,k,1); cout<<ans<<endl; } return 0; }