发现这种合并区间的题目还可以这么玩
给你n段时间 然后问没被占用的时间是多少
题目所给的区间是右开的导致我wa
好多人5e5*1440的暴力跑出来的时间居然只是我的两倍 不懂....
所以并查集并没有跑的很快 奇怪....
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <math.h> 6 #include <map> 7 #include <limits.h> 8 using namespace std; 9 typedef long long ll; 10 const int maxn = 5e5+100; 11 int par[maxn]; 12 int l[maxn],r[maxn]; 13 bool vis[maxn]; 14 void init(int n_) 15 { 16 for(int i=0;i<=n_;i++) 17 { 18 par[i] = i; 19 l[i] = r[i] = i; 20 } 21 memset(vis,false,sizeof(vis)); 22 } 23 int find(int x) 24 { 25 if(x!=par[x]) 26 { 27 return par[x] = find(par[x]); 28 } 29 return x; 30 } 31 void unite(int x,int y) 32 { 33 x = find(x); 34 y = find(y); 35 if(x==y) return ; 36 par[x] = y; 37 l[y] = min(l[y],l[x]); 38 r[y] = max(r[y],r[x]); 39 40 return ; 41 } 42 void make(int x,int y) 43 { 44 int pre = x; 45 for(int i=x;i<y;i==r[find(i)]?i++:i=r[find(i)]) 46 { 47 //cout<<i<<r[i]<<endl; 48 if(vis[i]) 49 { 50 pre = i; 51 continue; 52 } 53 vis[i] = true; 54 unite(pre,x); 55 pre = i; 56 } 57 } 58 int main() 59 { 60 int n; 61 int lim = 24*60; 62 while(scanf("%d",&n)!=EOF) 63 { 64 init(lim); 65 int L = 0,R = 0,a,b,c,d; 66 for(int i=0;i<n;i++) 67 { 68 scanf("%d:%d %d:%d",&a,&b,&c,&d); 69 L = a*60+b; 70 R = c*60+d; 71 make(L,R); 72 73 } 74 int ans = 0; 75 for(int i=0;i<lim;i++) 76 { 77 if(false==vis[i]) ans++; 78 } 79 printf("%d ",ans); 80 } 81 return 0; 82 }