我是题面

题意很清晰,这种题,我们当然还是有两种方法来做啦

方法一:找规律

读完题我们来看样例,通过样例一已我们大概可以看出,答案或许是\(n*2^{k+1}\)

肯定不能这么简单对吧,那就来看样例二,难道答案是\(n*2^{k+1}-k\)或者是\(n*2^{k+1}-2^{k-1}\)也有可能是\(n*2^{k+1}-2^k+1\)

通过样例三可得,答案是\(n*2^{k+1}-2^k+1\)

方法二:数学证明

每个月都是乘2,所以第i个月取走一个对第j个月的影响就是\(2^{j-i}(i<j)\)

那么每个月都会对最后一个月产生影响,影响总和是$ \sum _ {i=0} ^ {k-1} 2^i $,也就是\(2^k-1\)

这是负的影响,正的影响很容易算,就是\(n*2^{k+1}\)

说白了,每个月要么直接乘二,要么-1再乘二,我们把这个-1提出来,就分成了上面所说的正贡献和负贡献

千万别忘了特判等于零,还有直接乘会爆long long

下面放代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc getchar
#define mo 1000000007
using namespace std;

inline ll read(){
    ll a=0;int f=0;char p=gc();
    while(!isdigit(p)){f|=p=='-';p=gc();}
    while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
    return f?-a:a;
}

ll n,k,k1,e=2,sum=1;
inline ll cheng(ll a,ll b){
    ll sum=0;
    while(b){
        if(b&1)sum=(sum+a)%mo;
        a=(a<<1)%mo;b>>=1;
    }
    return sum;
}

int main(){
    n=read();k1=k=read();++k;
    if(n==0){
        puts("0");
        return 0;
    }k%=mo-1;
    while(k){
        if(k&1)n=cheng(n,e)%mo;
        e=cheng(e,e)%mo;k>>=1;
    }e=2;k1%=mo-1;
    while(k1){
        if(k1&1)sum=cheng(sum,e)%mo;
        e=cheng(e,e)%mo;k1>>=1;
    }
    --sum;if(sum<0)sum+=mo;
    printf("%lld\n",((n-sum)%mo+mo)%mo);
    return 0;
}

不要抄代码哦