当前位置:
首页 >
洛谷P2480:古代猪文(中国剩余定理)(欧拉定理)
发布时间:2023/12/3
49
豆豆
生活随笔
收集整理的这篇文章主要介绍了
洛谷P2480:古代猪文(中国剩余定理)(欧拉定理)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
传送门
文章目录
- 题目描述
- 解析
- 总结
- 代码
题目描述
解析
简单来说,就是求:
g∑C(d,n)(d是n的约数)mod 999911659
可以先特判一下,999911659|g时,答案为0
否则,可以通过欧拉定理转化为:
g∑C(d,n)(d是n的约数)mod999911658 mod 999911659
取完模之后,指数已经限制在了一个较小的范围,如果求出其值,就可以用快速幂解决
现在考虑求这个指数:
∑C(d,n)(d是n的约数)mod999911658
面对这样较大的组合数取模,容易想到用卢卡斯定理解决
但是问题在于本题的模数太大
所以我们考虑对这个模数进行质因数分解:
999911658=234679*35617
如果对这四个模数分别取模,就能把模数限制在一个可以接受的大小,并建立出4个同余方程
然后再利用中国剩余定理,解出这个指数即可
总结
本题的关键在于遇见大模数后进行质因数分解在进行中国剩余定理的转化
代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define ll long long #define int long long const int N=3e5+100; const ll mod=999911658; const ll Mod=999911659; ll ksm(ll x,ll o){ll ans=1,res=x%Mod;while(o){if(o&1) ans=(ans*res)%Mod;res=(res*res)%Mod;o>>=1;}return ans%Mod; } ll n; ll g; ll m[5]={0,2,3,4679,35617},M[5],MM,t[5]; ll d[N],num; void divide(ll x){int top=floor(sqrt(x));d[++num]=1;for(int i=2;i<=top;i++){if(x%i==0){d[++num]=i;if(n/i!=i) d[++num]=n/i;}}d[++num]=x;return; } ll ni[5][N],jc[N]; ll a[5];ll C(int k,ll d,ll n){if(d>n) return 0;if(d==n) return 1;return (jc[n]*ni[k][d]*ni[k][n-d])%m[k]; } ll lucas(int k,ll d,ll n){if(d==n) return 1;if(d>n) return 0;return (C(k,d%m[k],n%m[k])%m[k])*lucas(k,d/m[k],n/m[k])%m[k]; } void gcd(ll a,ll b,ll &x,ll &y){if(b==0){x=1;y=0;return;}gcd(b,a%b,x,y);int o=y;y=x-a/b*y;x=o;y%=mod;x%=mod; } signed main(){scanf("%lld%lld",&n,&g);if(g%Mod==0) {printf("0");return 0;}divide(n);jc[0]=jc[1]=1;for(int i=1;i<=4;i++) ni[i][0]=ni[i][1]=1;for(int i=2;i<=35167;i++){jc[i]=(jc[i-1]*i)%mod;for(int j=1;j<=4;j++) ni[j][i]=((m[j]-m[j]/i)*ni[j][m[j]%i])%m[j];}for(int i=2;i<=35167;i++) for(int j=1;j<=4;j++)ni[j][i]=(ni[j][i]*ni[j][i-1])%m[j];for(int i=1;i<=num;i++){for(int j=1;j<=4;j++){a[j]=(a[j]+lucas(j,d[i],n))%m[j];//printf("d=%lld mod=%lld ans=%lld\n",d[i],m[j],lucas(j,d[i],n)%m[j]);}}MM=mod;ll ans=0;for(int i=1;i<=4;i++){M[i]=MM/m[i];ll o;gcd(M[i],m[i],t[i],o);ans+=(t[i]*M[i]*a[i])%mod;ans%=mod;} // for(int j=1;j<=4;j++){ // printf("k=%d mod=%d:\n",j,m[j]){ // for(int i=1;i<=num;i++){ // printf // } // } // }ans%=MM;while(ans<0) ans+=MM;printf("%lld\n",ksm(g,ans)%Mod);return 0; } /* 4 5 1 5 2 7 3 4 2 */总结
以上是生活随笔为你收集整理的洛谷P2480:古代猪文(中国剩余定理)(欧拉定理)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 笔记本处理器还能比台式机更牛联想启天M5
- 下一篇: 剪纸游戏(博弈论)(SG函数)