古代猪文[SDOI2010]
古代猪文[SDOI2010]
题目大意:求\(g^{ \sum_{k|n} C_n^k}mod\ 999911659\)
前置知识:
-
欧拉定理推论:
内容:若正整数\(a,p\)互质,则对于任意正整数\(b\),有\(a^b \equiv a^{b\ mod\ \phi(p)} mod\ p\)
证明:
\[设b=q\phi(p)+r,0 \le r\lt \phi(p),即r=b\ mod\ \phi(p) \\ a^b \equiv a^{q\phi(p)+r}\equiv(a^{\phi(p)})^q \times a^r \\ 由欧拉定理知:a^{\phi(p)} \equiv 1\ mod \ p\ \Rightarrow\ (a^{\phi(p)})^q \equiv 1^q \equiv 1\ mod \ p \\ 故a^b \equiv (a^{\phi(p)})^q \times a^r \equiv a^r \equiv a^{b\ mod\ \phi(p)}mod\ p \] -
\(Lucas\)定理
内容:快速求组合数模质数,公式:\(C_n^m\ mod\ p=C_{\frac{n}{p}}^{\frac{m}{p}} \times C_{n\ mod\ p}^{m \ mod\ p}\)
int Lucas(int n,int m,int p) { if(n<p&&m<p) return C(n,m); return Lucas(n/p,m/p)*C(n%p,m%p)%p; }
-
中国剩余定理(CRT)
内容:已知\(n\)个非负整数\(a_1,a_2,...,a_n\)和\(n\)个互质的整数\(m_1,m_2,...,m_n\),且满足\(a_1\lt m_1,...,a_n \lt m_n\),求一个整数\(x\),满足:
\[\begin{cases} x \equiv a_1\ mod\ m_1 \\ x \equiv a_2\ mod\ m_2\\ \ \ \ \ \ \ \ \ \ ...\\ x \equiv a_n\ mod\ m_n \end{cases} \tag{1} \]求解方法:令\(M=\prod_{i = 1}^{n}m_i\),\(M_i=\frac{M}{m_i}\),且\(y_i\)为\(M_i\)模\(m_i\)意义下的逆元(\(M_iy_i \equiv 1\ mod\ m_i\))
则\(x=(\sum_{i=1}^na_iy_iM_i)\ mod\ M=(\sum_{i=1}^na_iM_i^{\phi(m_i)})\ mod\ M\)
本题解法
由于\(999911659\)是质数,故\(\phi(999911659)=999911658\)
\(g^{ \sum_{k|n} C_n^k}mod\ 999911659 \Rightarrow\ g^{ \sum_{k|n} C_n^k} \equiv g^{ \sum_{k|n} C_n^k\ mod\ \phi(999911659)} \equiv g^{ \sum_{k|n} C_n^k\ mod\ 999911658}\ mod\ 999911659\)
于是只要计算\(\sum_{k|n} C_n^k\ mod\ 999911658\)即可,但由于\(999911658\)不是质数,不好用\(Lucas\)定理处理,怎么办呢?
注意到\(999911658=2\times 3\times 4679\times 35617\),枚举\(k\),对于固定的\(k\),设\(m_1,m_2,m_3,m_4\) 分别为\(\sum_{k|n} C_n^k\)模 \(2,3,4679,35617\)之后的值,其中\(m_1,m_2,m_3,m_4\)可以用\(Lucas\)定理求。于是设 \(x=\sum_{k|n} C_n^k\ mod\ 999911658\),则
用\(CRT\)求\(x\)即可
,
#include <bits/stdc++.h>
#define lll __in128
#define ll long long
#define pb push_back
#define endl '\n'
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define fi first
#define se second
#define ls tr[rt].l
#define rs tr[rt].r
using namespace std;
const int N = 1e5 + 6;
const ll mod= 999911658;
ll frac[N],b[4]={2,3,4679,35617},c[5],ans;
ll qmi(ll x,ll y,ll p)
{
ll res=1;
while(y)
{
if(y&1) res=res*x%p;
x=x*x%p;
y>>=1;
}
return res;
}
ll C(ll n,ll m,ll p)
{
if(n<m) return 0;
return frac[n]*qmi(frac[m],p-2,p)%p*qmi(frac[n-m],p-2,p)%p;
}
ll Lucas(ll n,ll m,ll p)
{
if(n<p&&m<p) return C(n,m,p);
return Lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
void CRT()
{
for(int i=0;i<4;i++)
ans=(ans+c[i]*(mod/b[i])%mod*qmi(mod/b[i],b[i]-2,b[i]))%mod;
}
int main()
{
ll n,g;
cin>>n>>g;
frac[0]=1;
if(g%(mod+1)==0)
{
puts("0");
return 0;
}
for(int j=0;j<4;j++)
{
for(int i=1;i<=b[j];i++)
frac[i]=frac[i-1]*i%b[j];
for(ll i=1;i*i<=n;i++)
if(n%i==0)
{
c[j]=(c[j]+Lucas(n,i,b[j]))%b[j];
if(i*i!=n) c[j]=(c[j]+Lucas(n,n/i,b[j]))%b[j];
}
}
CRT();
cout<<qmi(g,ans,mod+1)<<endl;
return 0;
}