古代猪文

古代猪文

# 题意

给定$n$,$q$,求$q^{\Sigma \operatorname{din} C_{n}^{d}} \bmod p$,$p=999911659$

$1 \leqslant n, q \leq 10^{9}$

# 题解

就是对$n$的每一个正约数$d$,求$C_{n}^{d}$,因为$1 \leqslant n, q \leq 10^{9}$,所以不会有p的倍数,

所以只有$q=p$的时候原式才为$0$,所以当$q!=p$时,欧拉降幂$q^{\Sigma_{d m} c_{n}^{d}} \equiv q^{\Sigma_{d m} C_{n}^{d} \% p-1}(\bmod p)$

降幂后$p$非质数用$ExLucas$即可,将$p-1$分解质因数后为$2$、$3$、$4679$、$35617$,对于每个质因数,预处理所有阶乘,

每次$Lucas$的复杂度是$O\left(\log _{p} N \times p \times \log p\right)$

 

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int mod=999911658;
 5 ll n,q;
 6 ll a[5],b[5]={0,2,3,4679,35617};
 7 ll v[50010];
 8 void init(ll p){
 9     v[0]=1;
10     for(ll i=1;i<=p;i++){
11         v[i]=v[i-1]*i%p;
12     }
13 }
14 ll qmi(ll a,ll b,ll p){
15     ll res=1;
16     while(b){
17         if(b&1) res=res*a%p;
18         a=a*a%p;
19         b>>=1;
20     }
21     return res;
22 }
23 ll exgcd(ll a,ll b,ll &x,ll &y){
24     if(!b){
25         x=1,y=0;
26         return a;
27     }
28     ll d=exgcd(b,a%b,y,x);
29     y-=(a/b)*x;
30     return d;
31 }
32 vector<ll> get_divisor(ll n){
33     vector<ll>res;
34     for(ll d =1 ;d<=n/d;d++){
35         if(n%d==0){
36             res.push_back(d);
37             if(d*d!=n)
38                 res.push_back(n/d);
39         }
40     }
41     sort(res.begin(),res.end());
42     return res;
43 }
44 ll CRT(){
45     ll M=1;
46     for(int i=1;i<=4;i++){
47         M*=b[i];
48     }
49     ll res=0;
50     for(int i=1;i<=4;i++){
51         ll x,y;
52         ll tmp=M/b[i];
53         exgcd(tmp,b[i],x,y);
54         res=(res+tmp*x*a[i])%M;
55     }
56     return ((res+M)%M)%M;
57 }
58 ll C(ll n, ll m, ll p){
59     if(n<m) return 0;if(!n) return 1;
60     return v[n] * qmi(v[m],p-2,p) % p * qmi(v[n-m],p-2,p)%p;
61 }
62 ll lucas(ll n,ll m,ll p){
63     if(n<m) return 0;if(!n) return 1;
64     if(n<p&&m<p) return C(n,m,p);
65     return (ll)C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
66 }
67 int main(){
68     cin>>n>>q;
69     if(q==mod+1) {
70         puts("0");return 0;
71     }
72     auto d=get_divisor(n);
73     for(int i=1;i<=4;i++){
74         init(b[i]);
75         for(int j=0;j<d.size();j++){
76             a[i]=(a[i]+lucas(n,d[j],b[i]))%b[i];
77         }
78     }
79     ll ans=CRT();
80     cout<<qmi(q,ans,mod+1)<<endl;
81 }

 

posted @ 2020-04-20 22:18  Hyx'  阅读(233)  评论(0编辑  收藏  举报