Santa Claus and Tangerines

Santa Claus and Tangerines

题目链接:http://codeforces.com/contest/752/problem/E

二分

显然直接求答案并不是很容易,于是我们将其转化为判定性问题:二分解x,验证是否能分成k个x。

于是要点就在于check函数:

由于奇偶的原因,每个ai分出来的并不是2的幂次(比如当ai=11,x=3时,可以将ai分成3部分5,3,3)。

但是稍作思考,可以发现还是与2的幂次有关:

例如,当ai=6:48,x=3时,

aipart1part2num
6332
    
10552
11563
12664
    
2010104
2110115
2211116
2311127
2412128
    
4020208
4120219
42212110
43212211
44222212
45222313
46232314
47232415
48242416

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

若ai=44,因为40<=ai<=48,故num=16-(48-ai);

若ai=38,因为24<=ai<40,故num=8.

 

这种做法的时间复杂度为O(n×lgA×lglgA)

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 1000005
 4 using namespace std;
 5 typedef long long ll;
 6 ll n,k,a[N],p[28];
 7 void init(){
 8     p[0]=1;
 9     for(ll i=1;i<28;++i)
10         p[i]=p[i-1]<<1;
11 }
12 bool check(ll x){
13     if(!x)return 0;
14     ll sum=0;
15     for(ll i=0;i<n;++i){
16         ll t=a[i]/x;
17         ll up=*upper_bound(p,p+27,t);
18         if(up*x-up/2<=a[i])sum+=up-(up*x-a[i]);
19         else sum+=up/2;
20     }
21     return sum>=k;
22 }
23 int main(void){
24     scanf("%I64d%I64d",&n,&k);
25     init();
26     for(ll i=0;i<n;++i)scanf("%I64d",a+i);
27     ll l=0,r=10000001,mid;
28     while(l+1<r){
29         mid=(r-l)/2+l;
30         if(check(mid))l=mid;
31         else r=mid-1;
32     }
33     if(check(r))printf("%I64d\n",r);
34     else if(check(l))printf("%I64d\n",l);
35     else printf("-1\n");
36 }

 

转载于:https://www.cnblogs.com/barrier/p/6221116.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值