题目来源:http://codeforces.com/problemset/problem/337/C
意思是给你n,m,k ;
一共有n道题目 你能回答出m道题 每当你连续答对k道 你的分数就翻倍
求你能得到的最小分数
贪心 把翻倍的分数尽量放在前面
然后就数学计算了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MOD 1000000009
using namespace std;
#define MAX 1000000
long long n,m,k;
long long exp_mod(long long a,long long n) //快速幂
{
long long t;
if(n==0) return 1%MOD;
if(n==1) return a%MOD;
t=exp_mod(a,n/2);
t=t*t%MOD;
if((n&1)==1) t=t*a%MOD;
return t;
}
int main()
{
while(~scanf("%I64d%I64d%I64d",&n,&m,&k))
{
if((n-m)*k>n)
printf("%I64d\n",m);
else
{
long long x=n-(n-m)*k; //剩下的长度
long long y=x/k; //剩下的长度可以取双倍的次数
long long sum=(exp_mod(2,y+1)-2+MOD)%MOD; //sum 倍的k;
sum=(sum*k)%MOD;
sum=(sum+x%k)%MOD; //加上余数
sum=(sum+(n-m)*k-(n-m))%MOD; //加上后面没有倍数的
printf("%I64d\n",sum);
}
}
}