[题解]EER1迫害

题目地址: 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;
}
原文地址:https://www.cnblogs.com/UssEnterprise/p/12459360.html