CSU 1364 Interview ST

   先用ST预处理一下,做到可以O(1)得到[l,r]最值

  然后枚举块的长度,在枚举每个块,这样的复杂度就是n/1+n/2+n/3+...+n/n     n有20W,这个前面这个式子的值差不多又240W,复杂度可以接受。。

  另外一开始想到一个做法,二分答案,但是经证实这样的的确确是错的

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 200005;
 6 const int mod = 9997;
 7 int d[maxn][25];
 8 int a[maxn];
 9 void init(int n)
10 {
11     int len = 0,s = 1;
12     while(s*2<n)
13     {
14         len++;s<<=1;
15     }
16     for(int i = 1;i<=n;++i)d[i][0] = a[i];
17     for(int j = 1;j<=len;++j)
18     {
19         int u = 1<<j;
20         for(int i = 1;i+u-1<=n;++i)
21             d[i][j] = max(d[i][j-1],d[i+(u>>1)][j-1]);
22     }
23 
24 }
25 int query(int l,int r,int len)
26 {
27     return max(d[l][len],d[r-(1<<len)+1][len]);
28 }
29 int main()
30 {
31     int n, k;
32     while(~scanf("%d%d",&n,&k))
33     {
34         if(n+k<0)return 0;
35         int sum = 0;
36         for(int i = 1;i<=n;++i)scanf("%d",&a[i]);
37         init(n);
38         int ans = -1;
39         for(int i = n;i>=1;--i)
40         {
41 
42             int len = 0,s = 1;
43             while(s*2<i)
44             {
45                 len++;s<<=1;
46             }
47             sum = 0;
48             int m = n/i;
49             for(int j = 1;j<=m;j++)
50             {
51                 sum+=query((j-1)*i,j*i,len);
52                 if(sum>k){ans = j;break;}//这里有坑,一直写ans = m WA到死了都。。
53             }
54         //printf("i=%d sum=%d\n",i,sum);
55             if(sum>k)break;
56         }
57         printf("%d\n",ans);
58     }
59     return 0;
60 }

 

posted on 2015-04-14 23:28  round_0  阅读(87)  评论(0编辑  收藏  举报

导航