【数论】[SDOI2010]古代猪文

大概就是求这个:

$$G^sum_{k|N} C_{n}^{k}$$

显然只要把后面的$sum_{k|N}C_{n}^{k}$求出来就好了

几个要用的定理:

欧拉定理的推论:(a和n互质)

$$a^b equiv a^{b mod varphi(n)} mod n$$

中国剩余定理:

$$x_0=sum frac{M}{m_i}*t_i*a_i$$

卢卡斯定理:

$$C_{n}^{m} equiv C_{n mod mod}^{m mod mod}*C_{frac{n}{mod}}^{frac{m}{mod}} (mod mod)$$

先用欧拉定理推论有:

$sum_{k|N} C_{n}^{k}$可以等价为$ sum_{k|N} C_{n}^{k} mod varphi(mod)$

因为999911659是质数,所以显然有$varphi(mod)=mod-1$

所以现在我们只要求$ sum_{k|N} C_{n}^{k} mod (mod-1)$即可

但是$mod-1$不是质数,卢卡斯定理不适用...

莫非...我们要打一个扩展......

其实并不用!

我们把$mod-1$分解因数有$$999911659=2*3*4679*35617$$

所以就可以做了,把每一个因数都做模数跑一遍,最后用CRT把解合并起来,跑快速幂即可

做这题真的可以复习好多数论知识qwq~

 1 #include<bits/stdc++.h>
 2 #define int long long 
 3 #define writeln(x)  write(x),puts("")
 4 #define writep(x)   write(x),putchar(' ')
 5 using namespace std;
 6 inline int read(){
 7     int ans=0,f=1;char chr=getchar();
 8     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
 9     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
10     return ans*f;
11 }void write(int x){
12     if(x<0) putchar('-'),x=-x;
13     if(x>9) write(x/10);
14     putchar(x%10+'0');
15 }const int P = 999911659,M = 1e6+5;
16 int fac[M],n,m,b[6]={0,2,3,4679,35617},a[M];
17 int ksm(int x,int p,int mod){
18     if(p==0)return 1ll;
19     if(p==1)return x%mod;
20     int t=ksm(x,p>>1,mod);
21     if(p&1)return t*t%mod*x%mod;
22     return t*t%mod;
23 }
24 inline void Pre(int mod){fac[0]=1;for(int i=1;i<=mod;i++) fac[i]=fac[i-1]*i%mod;}
25 inline int inv(int x,int mod){return ksm(x,mod-2,mod);}
26 int C(int x,int y,int mod){//Lucas
27     if(x<y) return 0;
28     if(x<mod&&y<mod) return fac[x]*inv(fac[y],mod)%mod*inv(fac[x-y],mod)%mod;
29     return C(x/mod,y/mod,mod)*C(x%mod,y%mod,mod)%mod;
30 }void exgcd(int a,int b,int &x,int &y){
31     if(b==0) return x=1,y=0,void();
32     exgcd(b,a%b,x,y);
33     int t=x;x=y;y=t-a/b*y;
34 }inline int CRT(){
35     int M=P-1,ans=0;
36     for(int i=1;i<=4;i++){
37         int m=M/b[i],t,p;
38         exgcd(m,b[i],t,p);
39         t=((t%b[i])+b[i])%b[i];
40         ans=(ans+t*a[i]*m)%M;
41     }return ans;
42 }inline void Solve(){
43     for(int k=1;k<=4;k++){
44         int mod=b[k];Pre(mod);
45         for(int i=1;i*i<=n;i++)
46             if(n%i==0){
47                 a[k]=(a[k]+C(n,i,mod))%mod;
48                 if(i*i!=n)a[k]=(a[k]+C(n,n/i,mod))%mod;
49             }
50     }cout<<ksm(m,CRT(),P);
51 }signed main(){
52     n=read(),m=read();
53     if(m%P==0) return puts("0"),0;
54     Solve();
55     return 0;
56 }
原文地址:https://www.cnblogs.com/zhenglw/p/11628187.html