题目大意是一段长为1e7的线段,现在有 n 次区间涂色操作,之后的涂色会覆盖之前的涂色,问n次操作后线段上有多少种颜色。而实现的问题在于1e7过大,无法开线段树的四倍空间,所以我们需要进行离散化,这题数据很水,如果只是简单的对操作的左右坐标离散化也能过,但如果考虑以下的输入就会发现这种离散化是不全面的。
2
3
1 4
1 10
6 10
3
2 4
1 2
4 5
它遗漏 如 5 3这种孤立出来的部分。所以第一次离散化后我们需要将离散化坐标数组里不相邻的坐标中再插入数字,maxn也就由 2*n 改成了 4*n-1。
1 #pragma optimize("O3","unroll-loops") 2 #pragma target("avx3") 3 4 #include <cstdio> 5 #include <utility> 6 #include <algorithm> 7 #include <vector> 8 using namespace std; 9 #define Lson(x) ((x)<<1) 10 #define Rson(x) ((x)<<1|1) 11 typedef pair<int , int > pii; 12 const int maxn = 4e4; 13 const pii KONG = make_pair(0,0); 14 pii lazy[(maxn<<2)+10]; 15 bool vis[10000+4]; 16 17 void build(int s,int t,int p){ 18 if(s==t){ 19 lazy[p] = KONG; 20 return; 21 } 22 lazy[p] = KONG; 23 int mid = (s+t) >> 1; 24 build(s,mid,Lson(p)); 25 build(mid+1,t,Rson(p)); 26 } 27 28 void update(int L,int R,pii C,int s,int t,int p){ 29 if(L == s && t == R){ 30 lazy[p] = max(C,lazy[p]); 31 return; 32 } 33 int mid = (s+t) >> 1; 34 if(R <= mid) update(L,R,C,s,mid,Lson(p)); 35 else if(L>mid) update(L,R,C,mid+1,t,Rson(p)); 36 else update(L,mid,C,s,mid,Lson(p)),update(mid+1,R,C,mid+1,t,Rson(p)); 37 } 38 39 void DFS(int s,int t,int p,pii col){ 40 col = max(col,lazy[p]); 41 if(s == t){ 42 vis[col.second] = true; 43 return; 44 } 45 int mid = (s + t) >> 1; 46 DFS(s,mid,Lson(p),col); 47 DFS(mid + 1,t,Rson(p),col); 48 } 49 50 int main(){ 51 int cntcase; 52 scanf("%d",&cntcase); 53 while(cntcase--){ 54 build(1,maxn,1); 55 short n; 56 scanf("%hd",&n); 57 vector < pair< int ,int > > INPUT(n+1); 58 vector<int> discrete; 59 for(short i = 1;i<=n;++i){ 60 int L,R; 61 scanf("%d%d",&L,&R); 62 discrete.push_back(L); 63 discrete.push_back(R); 64 INPUT[i] = make_pair(L,R); 65 } 66 sort(discrete.begin(),discrete.end()); 67 int bound = unique(discrete.begin() , discrete.end()) - discrete.begin(); 68 69 vector< int > realdis(discrete.begin(),discrete.begin() + bound); 70 for(int i=0;i<bound-1;++i){ 71 if(realdis[i] + 1 != realdis[i+1]){ 72 realdis.push_back(realdis[i] + 1); 73 } 74 } 75 sort(realdis.begin(),realdis.end()); 76 77 for(short i=1;i<=n;++i){ 78 int L,R; 79 L = INPUT[i].first , R = INPUT[i].second; 80 L = lower_bound(realdis.begin(),realdis.end() , L ) - realdis.begin() + 1; 81 R = lower_bound(realdis.begin(),realdis.end() , R ) - realdis.begin() + 1; 82 vis[i] = false; 83 pii color = make_pair(i,i); 84 update(L,R,color,1,maxn,1); 85 } 86 DFS(1,maxn,1,KONG); 87 int ans = 0; 88 for(short i=1;i<=n;++i) 89 if(vis[i]) ans++; 90 printf("%d ",ans); 91 } 92 return 0; 93 }