Description
LCJ报名参加了一个特殊的电视问答节目。这个节目共有n个问题,每回答正确1题,LCJ就会获得1分,而每当LCJ连续答对k题,那么他的现有得分乘以2,注意答对第K题后,是先加1分到总分中,再把总分乘以2,此时连续答对题目计数器会清零。现在LCJ成功对了m题,他想知道他的最小得分。因为这个数字可能很大,你只需要输出这个数对1,000,000,009取模的结果即可。

Input
仅一行,三个数n,m,k如题目描述。
2<=k<=n<=1090<=m<=n

Output
仅一行,一个数,LCJ的最小得分。

Sample Input
5 3 2

Sample Output
3

HINT

思路
每次答题得分的最小值一定是尽可能连续答对k1题,如果还有可以答对的题,那么都放在前面的空缺中。注意这道题要快速幂,由于连续答对km的得分为2(2(2(k)+k)+k...)=2m+2m1+...+2=2m+12,因此答案加上这个值再减去重复求的值就好了。

代码

#include <cstdio>

const long long mo=1000000009ll;

long long n,m,k,ans;

long long quickpow(long long a,long long b,long long m)
{
    int res=1;
    while(b)
    {
        if(b&1)
        {
            res=(res*a)%m;
            b--;
        }
        b/=2;
        a=(a*a)%m;
    }
    return res;
}

int main()
{
    scanf("%lld%lld%lld",&n,&m,&k);
    if(m<=n/k*(k-1))
    {
        ans=m;
    }
    else
    {
        ans=n/k*(k-1);
        m-=n/k*(k-1);
        if(m<=n%k)
        {
            ans+=m;
            ans%=mo;
        }
        else
        {
            ans+=n%k;
            ans%=mo;
            m-=n%k;
            ans+=m;
            ans+=(quickpow(2ll,m+1,mo)-2-m)*k;
            ans%=mo;
        }
    }
    printf("%lld\n",ans);
    return 0;
}