开始队友说是线段树,看了看貌似也是,上手敲了个嵌套的线段树,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\n",++kase,ans);
50     }
51     return 0;
52 }

 

posted on 2014-09-05 09:59  gfc  阅读(274)  评论(0编辑  收藏  举报