HDU --- 5446 Unknown Treasure 数论综合【Lucas定理 + 中国剩余定理 + 快速乘 + 思维】
2018-03-10 12:14
495 查看
传送门
//题意: 给出n,m,k. 下一行给出k个质数. 求Cmnmod∏pi.
//一看n,m的范围都很大, mod的数也很大, 那么肯定不是简单的做法, 首先需要分析题意有
所以X就是我们要求的值, 我们可以发现等式右边我们可以用Lucas算出每一个具体的值, 然后得到了一系列类似于同余方程的方程组, 然后应用中国剩余定理求解出这些方程组就可以得到我们最后要的答案了.
//Lucas定理:
C(n, m) % p = C(n / p, m / p) * C(n%p, m%p) % p
对于C(n / p, m / p),如果n / p 还是很大,可以递归下去,一直到世界的尽头.
既是代码中的Lucas函数.(其中p为质数)
//这道题可是数论上的比较综合的题目了. 所以根据步骤来就是了, 我建议的是每写完一个子函数就调用一下验证其正确性, 反正博主是这样做的, 然后就1A 了. xx.
AC Code
//总的来说, 如果能想到证明哪里, 那么这道题还是挺好做的!!!
//题意: 给出n,m,k. 下一行给出k个质数. 求Cmnmod∏pi.
//一看n,m的范围都很大, mod的数也很大, 那么肯定不是简单的做法, 首先需要分析题意有
所以X就是我们要求的值, 我们可以发现等式右边我们可以用Lucas算出每一个具体的值, 然后得到了一系列类似于同余方程的方程组, 然后应用中国剩余定理求解出这些方程组就可以得到我们最后要的答案了.
//Lucas定理:
C(n, m) % p = C(n / p, m / p) * C(n%p, m%p) % p
对于C(n / p, m / p),如果n / p 还是很大,可以递归下去,一直到世界的尽头.
既是代码中的Lucas函数.(其中p为质数)
//这道题可是数论上的比较综合的题目了. 所以根据步骤来就是了, 我建议的是每写完一个子函数就调用一下验证其正确性, 反正博主是这样做的, 然后就1A 了. xx.
AC Code
/** @Cain*/ const int maxn=15+5; ll n,m,k; ll modnum[maxn],yunum[maxn]; //求a * b % mod; 由于这道题的mod都很大,所以乘法都容易爆,故需要快速乘. ll mut_mod(ll a,ll b,ll mod) { ll res = 0; while(b){ if(b&1) res = (res + a) % mod; a = (a + a) % mod; b >>= 1; } return res; } //扩展GCD. ll ex_gcd(ll a,ll b,ll &x,ll &y) { if(!b){ x = 1; y = 0; return a; } ll r = ex_gcd(b,a%b,x,y); ll tmp = x; x = y ; y = tmp - a/b*y; return r; } //快速幂用于求逆元,虽然ex_gcd也行,但是我不会用. xx. ll qpow(ll x,ll y,ll mod) { ll res = 1; while(y){ if(y & 1) res = mut_mod(res,x,mod) % mod; x = mut_mod(x,x,mod) % mod; y >>= 1; } return res; } //n % mod 的逆元 ll inv(ll n,ll mod) { return qpow(n,mod-2,mod); } //求n! % mod ll fac(ll n,ll mod) { ll res = 1; for(int i=2;i<=n;i++) res = res * i % mod; return res; } //C(n, m) % mod ll Comb(ll n,ll m, ll mod) { if(m>n) return 0; return fac(n,mod) * inv(fac(m,mod),mod) % mod * inv(fac(n-m,mod),mod) % mod; } //卢卡斯定理,求C(n,m)%mod,且n,m,mod都很大. ll Lucas(ll n, ll m,ll mod){ return m ? Lucas(n/mod, m/mod, mod) * Comb(n%mod, m%mod,mod) % mod : 1; } //解一阶同余方程 ll tongyu() { ll M = modnum[1],R = yunum[1]; for(int i=2;i<=k;i++){ ll d = __gcd(modnum[i],M); ll c = yunum[i] - R; if(c%d) return -1; //无解 ll k1,k2; ex_gcd(M/d,modnum[i]/d,k1,k2); k1 = ( k1* c/d ) % (modnum[i] / d); R = R + k1*M; M = M / d * modnum[i]; R %= M; } if( R < 0) R += M; return R; } //以上所有的mod都要求是质数!!! void solve() { scanf("%lld%lld%lld",&n,&m,&k); for(int i=1;i<=k;i++) scanf("%lld",&modnum[i]); for(int i=1;i<=k;i++) yunum[i] = Lucas(n,m,modnum[i]); printf("%lld\n",tongyu()); }
//总的来说, 如果能想到证明哪里, 那么这道题还是挺好做的!!!
相关文章推荐
- hdu 5446 lucas + 中国剩余定理 + 快速乘 (快速乘板子,中国剩余定理板子,lucas最新板子)
- HDU 5446 Lucas + 中国剩余定理 + 快速乘法
- HDU 5446 Lucas 中国剩余定理 快速乘
- HDU 5446 Unknown Treasure(lucas+中国剩余定理 / CRT)
- hdu 5446 Unknown Treasure 中国剩余定理+lucas
- HDU 5446-Unknown Treasure(Lucas+中国剩余定理)
- 【中国剩余定理】【容斥原理】【快速乘法】【数论】HDU 5768 Lucky7
- HDU 5446 Unknown Treasure(Lucas定理+中国剩余定理)
- Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)
- HDU 5446 Unknown Treasure Lucas+中国剩余定理+按位乘
- HDU 5446 lucas定理 + 中国剩余定理
- HDU 5446 Unknown Treasure (Lucas + 中国剩余定理)
- hdu 5446 (中国剩余定理+Lucas定理)
- HDU 5446 (中国剩余定理 Lucas)
- HDU 5446 中国剩余定理+lucas
- HDU 5446 Unknown Treasure(lucas定理+中国剩余定理)——2015 ACM/ICPC Asia Regional Changchun Online
- hdu 5446 Unknown Treasure(lucas+中国剩余定理)
- hdu 5446 Unknown Treasure Lucas定理+中国剩余定理
- HDU - 5446 Unknown Treasure (数论部分定理的综合应用,lucas+CRT)
- 【中国剩余定理】【容斥原理】【快速乘法】【数论】HDU 5768 Lucky7