【例题】【费马小定理(降幂)、递推】NKOJ 3687 整数拆分

NKOJ 3687 整数拆分
时间限制 : - 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

思路:
1、先求通项公式
设f[i][j]表示将i分为j个正整数的方案数
则在f[i][j]种方案中,可分为两类,第一类可由f[i-1][j-1]各方案加一项1所得,如f[5][3]中{3+1+1} {1+3+1} {1+1+3} {1+2+2} {2+1+2} {2+2+1} 1、2、6方案可由f[4][2]:{3+1} {1+3} {2+2} 三种方案加一项1所得,第二类可由f[i-1][j]各方案中一项加上1所得,如f[5][3]中 3、4、5方案可由f[4][3]: {1+2+1} {2+1+1} {1+2+1} 得到。
所以得到递推式:f[i][j]=f[i-1][j-1]+f[i-1][j];
即杨辉三角…..
所以通项公式为ans=2^(n-1)%d d=1,000,000,007;

2、注意到1<=N<=10^100000
所以需要降幂
根据费马小定理推论:(a^b%p=a^(b%(p-1))%p)
设m=n%(d-1) d=1,000,000,007;
则ans=2^(m-1)%d;

代码:

#include<cstdio> 
#include<iostream> 
using namespace std; 
#define ll long long  
const ll d=1000000007; 

ll power(ll a,ll b,ll c) 
{ 
    a%=c; 
    ll ans=1; 
    while(b) 
    { 
        if(b&1) ans=(ans*a)%c; 
        b>>=1; 
        a=(a*a)%c; 
    } 
    return ans; 
} 

int main() 
{ 
    string a;cin>>a; 
    int len=a.length();
    ll m=0; 
    for(int i=0;i<len;i++) m=(m*10+a[i]-'0')%(d-1); 
    if(m==0) m=d-1; 
    printf("%I64d",power(2,m-1,d)); 
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值