10%的数据中,1 <= N <= 50;
20%的数据中,1 <= N <= 1000;
40%的数据中,1 <= N <= 100000;
100%的数据中,1 <= G <= 1000000000,1 <= N <= 1000000000。
求g^N %p N满足所以n的因子c(n,k) n%k==0 之和;
感觉有点难求解。
N,g的范围都是10^9次方大。
1.首先打出10^9的所以因子,10^3的时间。
2.求所以的C(n,k)%p (n%k==0 )之和。
这个有难度,关键也是在这边.
求得之后,用N表示。
3.g^N%mod 快速幂可以解决这个问题。
由于mod = 999911659是一个素数,所以 p 就不是素数了。因为p=mod-1;
那么一个很大的问题摆在面C(n,k)%p; 由于p不是素数不能直接用Lucas定理解决。
只能进行拆分,把p拆分成素数。然后用中国剩余定理求。
恩恩,999911658 有唯一分解定理可知 999911658 = 2 * 3* 4679 * 35617;
这样就拆分成四个素数。
这样就可以做了。
在最初的代码中,分别筛选了不同素数 2 , 3, 4679, 35617的阶乘取模,其实我们可以用一个公共的数取模。
直接用999911658先打一个表即可。
1 /* 2 2 1 3 3 1 4 4679 1 5 35617 1 6 */ 7 #include<iostream> 8 #include<stdio.h> 9 #include<cstring> 10 #include<cstdlib> 11 using namespace std; 12 typedef long long LL; 13 14 const LL mod = 999911659; 15 LL jc[4][35621]; 16 LL yz[100001],len; 17 LL mi[5]={0,2,3,4679,35617}; 18 LL bi[5]; 19 void init() 20 { 21 int i,j; 22 for(i=0;i<4;i++) 23 { 24 jc[i][0]=1; 25 for(j=1;j<=mi[i+1];j++) 26 jc[i][j]=(jc[i][j-1]*j)%mi[i+1]; 27 } 28 } 29 LL pow_mod(LL a,LL n,LL p) 30 { 31 a=a%p; 32 LL ans=1; 33 if(n<=0)return ans; 34 while(n) 35 { 36 if(n&1) ans=(ans*a)%p; 37 n=n>>1; 38 a=(a*a)%p; 39 } 40 return ans; 41 } 42 LL C(LL n,LL m,LL p,LL t) 43 { 44 if(n<m) return 0;//!! 45 if(m>n-m) m=n-m; 46 LL sum1=jc[t][n]%p; 47 LL sum2=((jc[t][m]%p)*(jc[t][n-m]%p))%p; 48 sum1=(sum1*pow_mod(sum2,p-2,p))%p; 49 return sum1; 50 } 51 LL Lucas(LL n,LL m,LL p,LL t) 52 { 53 LL ans=1; 54 while(n&&m&&ans) 55 { 56 ans=ans*C(n%p,m%p,p,t); 57 n=n/p; 58 m=m/p; 59 } 60 return ans; 61 } 62 LL Ex_GCD(LL a,LL b,LL &x,LL& y) 63 { 64 if(b==0) 65 { 66 x=1; 67 y=0; 68 return a; 69 } 70 LL g=Ex_GCD(b,a%b,x,y); 71 LL hxl=x-(a/b)*y; 72 x=y; 73 y=hxl; 74 return g; 75 } 76 LL china(LL b[],LL m[],LL len) 77 { 78 LL i,x,y,M,sum=1,hxl=0; 79 for(i=1;i<=len;i++) 80 sum=sum*m[i]; 81 for(i=1;i<=len;i++) 82 { 83 M=sum/m[i]; 84 Ex_GCD(m[i],M,x,y); 85 hxl=(hxl+M*y*b[i])%sum; 86 } 87 if(hxl>0) 88 return hxl; 89 else return hxl+sum; 90 } 91 void solve(LL n,LL g) 92 { 93 LL i,j; 94 memset(bi,0,sizeof(bi)); 95 for(i=1;i<=4;i++) 96 { 97 for(j=1;j<=len;j++) 98 bi[i]=(bi[i]+Lucas(n,yz[j],mi[i],i-1))%mi[i]; 99 } 100 LL ans=china(bi,mi,4); 101 ans=pow_mod(g,ans,mod); 102 printf("%lld\n",ans); 103 } 104 int main() 105 { 106 init(); 107 LL n,g,i,k; 108 while(scanf("%lld%lld",&n,&g)>0) 109 { 110 len=1; 111 yz[1]=1; 112 if(n!=1) yz[++len]=n; 113 for(i=2;i*i<=n;i++) 114 { 115 if(n%i==0) 116 { 117 yz[++len]=i; 118 k=n/i; 119 if(k!=i) 120 yz[++len]=k; 121 } 122 } 123 solve(n,g); 124 } 125 return 0; 126 }
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 typedef long long LL; 7 8 const LL mod = 999911659; 9 LL jc[35618]; 10 LL yz[5001],len; 11 LL mi[5]={0,2,3,4679,35617}; 12 LL bi[5]; 13 void init() 14 { 15 int i; 16 jc[0]=1; 17 for(i=1;i<=35617;i++) 18 jc[i]=(jc[i-1]*i)%999911658; 19 } 20 LL pow_mod(LL a,LL n,LL p) 21 { 22 a=a%p; 23 LL ans=1; 24 if(n<=0)return ans; 25 while(n) 26 { 27 if(n&1) ans=(ans*a)%p; 28 n=n>>1; 29 a=(a*a)%p; 30 } 31 return ans; 32 } 33 LL C(LL n,LL m,LL p) 34 { 35 if(n<m) return 0; 36 if(m>n-m) m=n-m; 37 LL sum1=jc[n]%p; 38 LL sum2=((jc[m]%p)*(jc[n-m]%p))%p; 39 sum1=(sum1*pow_mod(sum2,p-2,p))%p; 40 return sum1; 41 } 42 LL Lucas(LL n,LL m,LL p) 43 { 44 LL ans=1; 45 while(n&&m&&ans) 46 { 47 ans=ans*C(n%p,m%p,p); 48 n=n/p; 49 m=m/p; 50 } 51 return ans; 52 } 53 LL Ex_GCD(LL a,LL b,LL &x,LL& y) 54 { 55 if(b==0) 56 { 57 x=1; 58 y=0; 59 return a; 60 } 61 LL g=Ex_GCD(b,a%b,x,y); 62 LL hxl=x-(a/b)*y; 63 x=y; 64 y=hxl; 65 return g; 66 } 67 LL china(LL b[],LL m[],LL len) 68 { 69 LL i,d,x,y,M,sum=1,hxl=0; 70 for(i=1;i<=len;i++) 71 sum=sum*m[i]; 72 for(i=1;i<=len;i++) 73 { 74 M=sum/m[i]; 75 d=Ex_GCD(m[i],M,x,y); 76 hxl=(hxl+M*y*b[i])%sum; 77 } 78 if(hxl>0) 79 return hxl; 80 else 81 return hxl+sum; 82 } 83 void solve(LL n,LL g) 84 { 85 LL i,j; 86 memset(bi,0,sizeof(bi)); 87 for(i=1;i<=4;i++) 88 { 89 LL sum=0; 90 for(j=1;j<=len;j++) 91 sum=(sum+Lucas(n,yz[j],mi[i]))%(mi[i]); 92 bi[i]=sum; 93 } 94 LL ans=china(bi,mi,4); 95 ans=pow_mod(g,ans,mod); 96 printf("%lld\n",ans); 97 } 98 int main() 99 { 100 init(); 101 LL n,g,i,k; 102 while(scanf("%lld%lld",&n,&g)>0) 103 { 104 len=2; 105 yz[1]=1; 106 yz[2]=n; 107 for(i=2;i*i<=n;i++) 108 { 109 if(n%i==0) 110 { 111 yz[++len]=i; 112 k=n/i; 113 if(k!=i) 114 yz[++len]=k; 115 } 116 } 117 solve(n,g); 118 } 119 return 0; 120 }