NKOI 3687 整数划分

P3687  整数拆分
时间限制 : - MS   空间限制 : 65536 KB 评测说明 : 时限1000ms
问题描述

给你一个正整数N,F(x)表示把N拆分成x个正整数之和的方案数。
例如,当n=5时:
F(1)=1,方案为:{5}
F(2)=4,方案为:{1+4}  {4+1}  {2+3}  {3+2}
F(3)=6,方案为:{1+1+3}  {1+3+1}  {3+1+1}  {1+2+2}  {2+1+2}  {2+2+1} 
F(4)=4,方案为:{1+1+1+2}  {1+1+2+1}  {1+2+1+1}  {2+1+1+1}  
F(5)=1,方案为:{1+1+1+1+1} 
请你计算出F(1)+F(2)+......+F(N)
结果可能很大,mod 1,000,000,007 再输出!

输入格式

第一行,一个整数N

输出格式

一行,一个整数,表示所求的结果

样例输入

5

样例输出

16

提示

对于50%的数据1<=N<=100
对于100%的数据1<=N<=10100000

   当N=5的时候,我们可以想到将5分成1 1 1 1 1,那么根据题意则相当于将每i个数合为一个的总方案(0<=i<=n-1)
我们就可以发现题目就转化为了有N-1个空,在这n-1个空中放i个球的总方案
那么很明显,可以得到一个组合数的总和
因此用暴力可以发现规律,最终答案等于2^(n-1)
但是10的十万次方的数据,甚至都不能把输入数据直接用整数的形式存下来
因此我们可以想到使用费马小定理降幂
由于答案是2^(n-1) mod 1000000007,设p=1000000007 
因为p是质数,根据费马小定理:a^(p-1) ≡1(mod p) 我们有:
2^(p-1)%p=1
2^(n-1)%p=2^((n-1)%(p-1)) %p
即在2的各次方中将2的p-1次方全部模掉,那么剩下的就是我们要求的答案了
#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int mod=1e9+7;
char str[100005];
LL mg(LL a,LL b,LL mod){
	LL ans=1;
	while(b>0){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b=b>>1;
	}
	return ans;
}
int main(){
	LL i,ans,num=0;
    scanf("%s",str);
	int len=strlen(str);
	for(i=0;i<len;i++)
		num=(num*10+(str[i]-'0'))%(mod-1); 
	if(num==0)ans=mg(2,mod-2,mod);
	else ans=mg(2,num-1,mod);
	cout<<ans;
}




 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值