题目地址: P6195 [EER1]迫害
这个题要不给样例说明似乎就难了一点
本题是快速幂的应用
由于 (m) 是可自由确定,我们发现选取 (k*(n+1)) 是最优选择。根据二进制划分的原理,要想得到更多的组合(每个只用一遍) (m=2^k(n+1)) 最优。
以样例2为例
当 (n=2) 时我们可以得到如下方式组合
[1,1+1
]
然后添加 (m)
[1,1+1,3,3+1,3+1+1,6,6+1,6+1+1,6+3,6+3+1,6+3+1+1cdots
]
所以可得公式
[ans=(n+1)*2^m+n
]
当然最后要取模(不过就多%几遍就好了)
代码仅供参考,码风较为混乱
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define rg register
#define ll long long
#define int unsigned long long
namespace Enterprise{
inline int read(){
rg int s=0,f=0;
rg char ch=getchar();
while(not isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return f?-s:s;
}
int mod=1e9+7;
int n,m;
inline int ksm(int b){
int ans=1;
int p=2;
while(b){
if(b&1) ans=ans*p%mod;
b>>=1;
p=p*p%mod;
}
return ans;
}
inline void main(){
n=read(),m=read();
printf("%d",(((((n+1)%mod)*(ksm(m)-1)%mod)%mod+n)%mod));
}
}
signed main(){
Enterprise::main();
return 0;
}