Round #196 (Div. 2) C、Quiz

题目链接:http://codeforces.com/problemset/problem/337/C

1、以下是官方题解,我把它翻译成了中文,看懂了这个,就能AC这道题了。注意可能取余是负数,这时要在ans上加上mod才行。

Assume that Manao has doubled his score (i.e. gave k consecutive correct answers) exactly X times. Then the least possible score is obtained when this doublings happen in the beginning of the game, i.e., when he answers the first X*k questions and never manages to answer k consecutive questions after that. The correctness of this statement follows from the following: for any other scenario with X doublings, all of these doublings can be moved into the beginning and the total score will not increase. Hence, for X=1 Manao's minimum score is k*2+m-k: he answers k consecutive questions, the score doubles, then he answers m-k questions. For X=2 the minimum possible score is (k*2+k)*2+m-2*k, for X=3 — ((k*2+k)*2+k)*2+m-3*k. For the general case, a formula (2^1+2^2+...+2^X)*k + m-X*k = (2^(X+1)-2)*k + m-X*k is derived.

The abovementioned observation shows that the minimum score grows monotonically when X is increased, so all we need is to find the minimum feasible X. It should satisfy the inequalities X*k <= n and X + (n - n mod k) / k * (k-1) + n mod k >= m. More on the second inequality: Manao answered the first X*k questions, thus there are n-X*k left. Now he can answer at most k-1 question from each k questions. If k divides n-X*k (which is the same as k divides n), the inequality becomes X*k + (n-X*k) / k * (k-1) >= m, but the remainder complicates it a bit: X*k + (n - X*k - (n - X*k) mod k) / k * (k-1) + (n - X*k) mod k >= m. This formula can be simplified to the one written earlier. So, the minimum X is equal to max(0, m - (n - n mod k) / k * (k-1) - n mod k). You'll need exponentiation by squaring to compute the score corresponding to this value of X. Thus, the overall complexity of this solution is O(log(n)).
假设Manao已经让比分加倍了(例如,给出k个连续正确的答案)刚好x次。然后当这个加倍在游戏开始时发生的时候,最少可能的分数就被获得了——举个例子:当他回答了第一个x*k个问题而且再也没能回答k个连续问题。这句话的正确性是因为遵从了以下法则:对于其他任何加倍了x次的方案,所有的加倍能被移到开始而且总分不会增加。因此,对于x==1,Manao的最小分数是k*2+m-k:他回答了k个连续问题,分数加倍,然后他回答了m-k个问题。对于x=2,最小可能分数是(k*2+k)*2+m-2*k,对于x=3,最小可能分数是((k*2+k)*2+k)*2+m-3*k。对于整个样例,一个公式(2^1+2^2+...+2^x)*k + m-x*k = (2^(x+1)-2)*k + m-x*k就被推导出来了。
上述提到的观察表明了当x增加时最小分数是单调增加的,所以我们需要的就是找到最小可能的x值。它应该满足不等式x*k<=n而且x+(n-n mod k)/k*(k-1)+n mod k>=m。再补充说明第二个不等式:Manao回答了第一个x*k个问题,所以还有n-x*k个问题剩着。现在,每k个问题中,他可以回答至多k-1个问题。如果k能整除n-x*k(相当于k能整除n),不等式就变成了x*k + (n-x*k) / k * (k-1) >= m,但是余数使它复杂了一点:x*k + (n - x*k - (n - x*k) mod k) / k * (k-1) + (n - x*k) mod k >= m.这个公式可以被简化为第二个不等式。所以,最小x等于max(0, m - (n - n mod k) / k * (k-1) - n mod k).你将需要用快速幂来计算出与x相应的分数。所以,这个解的总体时间复杂度是O(log(n))。

#include <cstdio>
#define mod 1000000009
using namespace std;
long long pow(long long x,long long n)
{
    long long ret=1;
    while(n)
    {
        if(n&1)ret=ret*x%mod;
        x=x*x%mod;
        n/=2;
    }
    return ret;
}
int main()
{
    long long n,m,k;
    while(scanf("%I64d%I64d%I64d",&n,&m,&k)==3){
       long long x=m-(n-n%k)/k*(k-1)-n%k;
       if(x<0) x=0;
       long long ans=pow(2,x+1)-2;
       ans=(ans*k+m-x*k)%mod;
       if(ans<0) ans+=mod;
       printf("%I64d\n",ans);
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值