开始队友说是线段树,看了看貌似也是,上手敲了个嵌套的线段树,O(nlognlogn)的复杂度果断tle了 TAT
思路:对h[i]排序,对每次涨水退水,先用二分查找,再用一个数组保存当前点之后所有点被淹的次数;temp[bs(b[i-1])+1]++,temp[bs(a[i])+1]--;
最后遍历一遍temp数组,有大于等于k,则ans++。
ps:上次也看到一个卡线段树的,也是用这种方法写的,orz
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 100005 ; 8 9 int h[maxn]; 10 int a[maxn]; 11 int n,m,k; 12 13 int bs (int x){ 14 int l=0,r=n-1; 15 int mid=(l+r)/2; 16 while (l<r){//cout<<mid<<" "<<x<<"|"; 17 if (h[mid]<=x&&h[mid+1]>x) 18 return mid; 19 if (h[mid]<=x) 20 l=mid+1; 21 else r=mid-1; 22 mid=(l+r)/2; 23 } 24 return mid; 25 } 26 27 int main (){ 28 int kase=0; 29 while (~scanf ("%d%d%d",&n,&m,&k)){ 30 for (int i=0;i<n;i++) scanf ("%d",&h[i]); 31 sort (h,h+n); 32 memset (a,0,sizeof a); 33 int s,t,temp; 34 s=1; 35 for (int i=0;i<m;i++){ 36 scanf ("%d%d",&t,&temp); 37 a[bs(s)+1]++; 38 a[bs(t)+1]--; 39 40 s=temp; 41 } 42 int ans=0; 43 int acc=0; 44 for (int i=0;i<n;i++){ 45 acc+=a[i]; 46 if (acc>=k) 47 ans++; 48 } 49 printf ("Case %d: %d ",++kase,ans); 50 } 51 return 0; 52 }