HDU_4704_Sum_隔板原理、二项式定理、同余定理、费马小定理、快速幂
2014-10-22 09:59
543 查看
今天连A两道题,其实都是之前就知道怎么做了只不过没敲代码。
题意:
给一个小于10^100000的正整数,定义S(k)是把n分割成k个正整数的方法数,求( S(1)+...+S(n) )%(10^9+7)
输入:n
输出:( S(1)+...+S(n) )%(10^9+7)
首先根据隔板原理,S(K)=C(N-1,K-1),然后S(1)+..+S(n)根据二项式定理就等于2^(n-1),但是n极大,幂运算又不满足同余定理,这时可以应用费马小定理,
费马小定理:对一个素数mod,有( x^(mod-1) ) % mod = 1,即欧拉定理在mod为素数情况下的特例
为了把(n-1)缩小,把n-1变成(n-1) % (mod-1) + (n-1) / (mod-1) * (mod-1),然后分割开,加号右边的部分根据费马小定理等于1,左边的部分在n-1取模后变得很小,取模通过字符串存储同余定理完成。
代码如下:
题意:
给一个小于10^100000的正整数,定义S(k)是把n分割成k个正整数的方法数,求( S(1)+...+S(n) )%(10^9+7)
输入:n
输出:( S(1)+...+S(n) )%(10^9+7)
首先根据隔板原理,S(K)=C(N-1,K-1),然后S(1)+..+S(n)根据二项式定理就等于2^(n-1),但是n极大,幂运算又不满足同余定理,这时可以应用费马小定理,
费马小定理:对一个素数mod,有( x^(mod-1) ) % mod = 1,即欧拉定理在mod为素数情况下的特例
为了把(n-1)缩小,把n-1变成(n-1) % (mod-1) + (n-1) / (mod-1) * (mod-1),然后分割开,加号右边的部分根据费马小定理等于1,左边的部分在n-1取模后变得很小,取模通过字符串存储同余定理完成。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> using namespace std; #define mxn 100010 #define mod 1000000007 char a[mxn]; long long quick_power(long long n){ if(n==1) return 2; else if(!n) return 1; long long tem=quick_power(n/2); if(n%2) return tem*tem%mod*2%mod; return tem*tem%mod; } long long MOD(char in[]){ int len=strlen(in); long long ret=0; for(int i=0;i<len;++i) ret=(ret*10+in[i]-'0')%(mod-1); return ret; } int main(){ while(scanf("%s",a)!=EOF){ long long n=MOD(a); long long ans=quick_power(n-1); cout<<ans<<endl; } return 0; }
相关文章推荐
- HDU 4704 Sum (隔板原理 + 费马小定理)
- HDU 4704 Sum (隔板原理 + 费马小定理)
- HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)
- HDU 4704 SUM 整数快速幂+费马小定理
- 数论 --- 费马小定理 + 快速幂 HDU 4704 Sum
- HDU 4704 Sum 【隔板原理+费马小定理+快速幂】
- [HDU 4704] Sum · 费马小定理 & 快速幂
- HDU--4704 Sum【费马小定理,快速幂】
- 数论 --- 费马小定理 + 快速幂 HDU 4704 Sum
- HDU 4704 Sum 费马小定理+快速幂
- HDU 4704 Sum 费马小定理
- Hdu 4704 Sum -- 快速幂+高精度处理
- hdu 4704 Sum(隔板+费马小定理·大数取模)
- [数论]HDU 4704 Sum 费马小定理
- HDU 4704 Sum (费马小定理)
- HDU 4704 Sum (费马小定理)
- hdu 4704 sum 大整数取模+费马小定理+数快速幂
- hdu 4704 sum 费马小定理
- HUD 4704 Sum 费马小定理和快速幂
- 数论+快速幂-hdu-4704-Sum