[BZOJ 1951] 古代猪文

Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1951

 

Solution:

见过最长的数论题题面.......

 

一道数论的综合题,求解:

\[g^{\sum_{d|n} C_n^d}~mod~p\]

 

我们先看幂能否化简,

由费马小定理可知

\begin{aligned} \displaystyle ans &=  g^{\sum_{d|n} C_n^d}~mod~p  \\  &=g^{\sum_{d|n} C_n^d~mod~(p-1)}~mod~p  \end{aligned}

 

对于化简后的幂:

\[\sum_{d|n} C_n^d~mod~(p-1)\]

我们想到枚举每一个n的约数,使用Lucas定理求大组合数取模

 

但P-1=2*3*4679*35617,不是一个质数

于是我们以每一个质因子为模数算出最终的解

由于质因子之间是互质的,再用中华剩余定理合并结果算出最小的\[\sum_{d|n} C_n^d\],即为\[\sum_{d|n} C_n^d~mod~(p-1)\]

 

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=1e5+10;
const int MOD=999911659;

int quick_pow(ll a,ll b,int p) //快速幂
{
    ll ret=1;a%=p;
    while(b)
    {
        if(b&1) ret=ret*a%p;
        b>>=1;a=a*a%p; 
    }
    return ret;
}

int inv(ll a,int p){return quick_pow(a,p-2,p);}  //求逆元

int g,n,fac[4][MAXN],c[4];
int pri[]={2,3,4679,35617};

int C(int n,int m,int p)  //求组合数
{
    if(n>m) return 0;
    return 1ll*fac[p][m]*inv(1ll*fac[p][n]*fac[p][m-n],pri[p])%pri[p];
}

int Lucas(int n,int m,int p)  //Lucas定理
{
    if(m==0) return 1;
    return C(n%pri[p],m%pri[p],p)*Lucas(n/pri[p],m/pri[p],p)%pri[p];
}

ll CRT()  //中国剩余定理
{
    ll ret=0,p=MOD-1;
    for(int i=0;i<4;i++) 
        ret=(ret+1ll*p/pri[i]*inv(p/pri[i],pri[i])*c[i])%p;
    return ret%MOD;
}

int main()
{
    cin >> n >> g;
    if(g==MOD) return cout << 0,0;
    for(int i=0;i<4;i++)  //预处理阶乘
    {
        fac[i][0]=1;
        for(int j=1;j<=pri[i];j++)
            fac[i][j]=fac[i][j-1]*j%pri[i];
    }
    
    for(int i=0;i<4;i++)
        for(int j=1;j*j<=n;j++)
            if(n%j==0)
            {
                c[i]=(c[i]+Lucas(j,n,i))%pri[i];
                if(j*j!=n) c[i]=(c[i]+Lucas(n/j,n,i))%pri[i];
            }
    
    cout << quick_pow(g,CRT(),MOD);
    return 0;
}

 

Review:

1、如果模数为质数,

利用费马小定理对幂化简

 

2、遇到大组合数取模  ------->   Lucas定理

 

如果模数不为质数,质因数分解后分别求出结果再用中华剩余定理合并,套路啊……

 

3、中华剩余定理求解方法

(1)递推式地两两求解

(2)根据推导出的结论直接求解:

\[x=(\sum\limits_{i=1}^k c_i*{M\over m_i}*inv({M\over m_i},mi))\%M\]

posted @ 2018-05-25 15:41  NewErA  阅读(312)  评论(0编辑  收藏  举报