【HDU - 4704】Sum 【隔板法+费马小定理降幂】
2017-11-01 16:15
351 查看
分析: 我们可以将n划分为n 个1,然后我们分1就行了。 s(k) 为 从n-1个空中插入k-1个隔板,即C(n-1,k-1),现在要求C(n-1,0)+C(n-1,1)+C(n-1,2)…+C(n-1,n-1) ,由二项式定理公式 C(n,0)+C(n,1)+C(n,2)…C(n,n)= 2^n. 可知我们要求的是2^(n-1)
但是题目中的N太大了,无法计算,所有我们可以用费马小定理降幂,
费马小定理为 a^( p - 1) = 1 ( mod p ) 其中p为素数,同时gcd(a,p)==1。
所以 可以有降幂公式 a ^ n % p= a ^ ( n % ( p-1 ) ) %p ,因为不管多少个a^(p-1) 在p的模下都会是1,所以我们找到余数就行了。同时为了防止(n%(p-1))可能为负数 , 我们可以用 (n%(p-1)+p-1)%(p-1) 来找到最小的正整数余数。
将n降幂到mod级数,之后我们用快速幂就行了。
补充: 因为费马小定理是欧拉定理的特殊形式。
欧拉定理 a ^ phi (p) = 1 ( mod p ) ,其中gcd(a,p)==1 即可 。
同样可以转化为降幂形式 假如想求 a ^n % mod , 只要gcd(a,mod)==1,那么我们都可以转化 a ^ (n % phi(mod)) % mod如果n%phi(mod)也会出现负数的情况,处理方法同费马小定理的时候。假如mod为素数 , phi(mod)=mod-1,带入不就是费马小定理降幂了, 所以啊,都是欧拉定理的特殊形式。
代码
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>pii; #define first fi #define second se #define LL long long #define fread() freopen("in.txt","r",stdin) #define fwrite() freopen("out.txt","w",stdout) #define CLOSE() ios_base::sync_with_stdio(false) const int MAXN = 1e5; const int MAXM = 1e6; const int mod = 1e9+7 -1 ; // p - 1 const int inf = 0x3f3f3f3f; LL power(LL a,LL b,LL c){ LL s=1,base=a%c; while(b){ if(1&b) s=s*base%c; base=base*base%c; b>>=1; } return s; } char s[MAXN]; int main(){ CLOSE(); // fread(); // fwrite(); while(scanf("%s",s)!=EOF){ LL k=0; for(int i=0;s[i];i++) k=(k*10+s[i]-'0')%mod f22d ; // 注意这里 k - 1 可能为负数,所以我们要处理下。 printf("%lld\n",power(2ll,(k%mod-1)%mod,mod+1)); } return 0; }
相关文章推荐
- hdu 4704 Sum(组合,费马小定理,快速幂)
- HDU 4704 Sum(费马小定理,组合数学,快速幂)
- HDU4704:Sum(费马小定理 & 隔板法)
- HDOJ 题目4704 Sum(费马小定理,快速幂)
- hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)
- hdu 4704 Sum (整数和分解+高速幂+费马小定理降幂)
- HDU 4704 Sum (费马小定理+快速幂+整数和分解+欧拉降幂)
- hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)
- HDU 4704 Sum (费马定理+快速幂)
- hdu 4549 M斐波那契数列(费马小定理 + 二分快速幂 + 矩阵快速幂)
- HDU 4704 Sum
- hdu 4704 Sum-----2^高精度%p
- 数论+快速幂-hdu-4704-Sum
- 费马小定理 : 求逆元 降幂
- HDU 4704 Sum (费马小定理)
- hdu 4704 Sum(费马小定理)解题报告
- HDU 4704 Sum
- HDU 4704 Sum
- [数论]HDU 4704 Sum 费马小定理
- Hdu 4704 Sum -- 快速幂+高精度处理