标签:
先用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 }
标签:
原文地址:http://www.cnblogs.com/GJKACAC/p/4427303.html