HDU3486 RMQ
1 /*多么变态的一道题,交了18次*/ 2 3 4 #include<cstdio> 5 #include<cstring> 6 #include<cmath> 7 #define max(a,b) (a>b?a:b) 8 int dp[200005][20],llog2[200005];//用llog2数组进行优化 9 int n,k; 10 11 void DpMax(){ 12 for(int j=1;j<=llog2[n]+1;j++){//llog2 13 for(int i=1;i+(1<<j)-1<=n;i++){ 14 dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); 15 } 16 } 17 } 18 19 int GetMax(int L,int R){ 20 int j=llog2[R-L+1];//llog2 21 return max(dp[L][j],dp[R-(1<<j)+1][j]); 22 } 23 24 int work(){ 25 int pre_num = -1, pre_tot = -1, pre_sum; 26 for(int i = 1; i <= n; ++i) //分成i组 27 { 28 int num = n / i; //每组num个 29 int sum = num * i; //总的多少人 30 int tot = 0; 31 if(num == pre_num) //如果和前一次一样则从前一次继续累加即可 32 { 33 tot = pre_tot; 34 for(int j = pre_sum + num; j <= sum; j+= num) 35 { 36 tot += GetMax(j - num + 1, j); 37 if(tot > k) 38 return i; 39 } 40 pre_tot = tot; 41 pre_sum = sum; 42 } 43 else 44 { 45 for(int j = num; j <= sum; j += num) 46 { 47 tot += GetMax(j-num+1, j); 48 if(tot > k) 49 return i; 50 } 51 pre_num = num; 52 pre_tot = tot; 53 pre_sum = sum; 54 } 55 } 56 return -1; 57 } 58 59 int main(){ 60 for(int i=2;i<200005;++i){//llog2 61 llog2[i]=(i&(i-1))==0?llog2[i-1]+1:llog2[i-1]; 62 } 63 while(scanf("%d%d",&n,&k),n>0||k>0){ 64 memset(dp,0,sizeof(dp)); 65 for(int i=1;i<=n;i++){ 66 scanf("%d",&dp[i][0]); 67 } 68 DpMax(); 69 printf("%d\n",work()); 70 } 71 } 72 73 74
posted on 2013-07-05 18:27 Stomach_ache 阅读(153) 评论(0) 编辑 收藏 举报