bzoj1951 [SDOI2010]古代猪文
solution
理解完题意。发现就是求\(g^{\sum\limits_{k|n}C_n^k}\)。
利用欧拉降幂,可以将式子写成\(g^{\sum\limits_{k|n}C_n^k\%\phi(mod)}\)
只要想办法把指数求出来就行了。
看一下数据范围,发现\(n\)比较大,不能直接计算组合数。然后考虑用\(lucas\)。但是模数也比较大。
因为模数不是质数,对其进行质因数分解得到\(2,3,4679,35671\)。发现这四个质数都是可以进行\(lucas\)的。所以思路就很明显了,先将模数分解质因子,然后分别求出答案。得到四个形如\(\sum\limits_{k|n}C_n^k\equiv a_i(mod\ m_i)\)的式子。然后用\(CRT\)将其合并起来,得到\(\sum\limits_{k|n}C_n^k\%\phi(mod)\)
PS:因为欧拉降幂必须满足底数与模数互质,因为题目所给模数为质数,所以当\(g\)为所给模数倍数时不能使用欧拉降幂,而此时答案显然为\(0\),需要特判。
code
/*
* @Author: wxyww
* @Date: 2020-04-22 09:31:36
* @Last Modified time: 2020-04-22 09:52:12
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100010;
ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0'; c = getchar();
}
return x * f;
}
ll qm(ll x,ll y,ll mod) {
ll ret = 1;
for(;y;y >>= 1,x = x * x % mod)
if(y & 1) ret = ret * x % mod;
return ret;
}
int jc[N],inv[N];
ll C(int n,int m,int mod) {
if(n < m) return 0;
if(n < mod) return jc[n] * inv[m] % mod * inv[n - m] % mod;
return C(n % mod,m % mod,mod) * C(n / mod,m / mod,mod) % mod;
}
ll a[5];
ll b[5] = {0,2,3,4679,35617};
ll solve(int n,int mod) {
jc[0] = 1;
for(int i = 1;i < mod;++i) jc[i] = jc[i - 1] * i % mod;
inv[mod - 1] = qm(jc[mod - 1],mod - 2,mod);
// cout<<inv[mod - 1]<<endl;
for(int i = mod - 2;i >= 0;--i) inv[i] = inv[i + 1] * (i + 1) % mod;
ll ret = 0;
for(int i = 1;i * i <= n;++i) {
if(n % i) continue;
ret += C(n,i,mod);
ret %= mod;
if(i * i != n) ret += C(n,n / i,mod),ret %= mod;
// if(mod == 2) {
// printf("!!%d\n",C(n,i,mod));
// }
}
return ret;
}
int main() {
int n = read(),G = read();
if(G % 999911659 == 0) {
puts("0");return 0;
}
for(int i = 1;i <= 4;++i) {
a[i] = solve(n,b[i]);
// printf("%d\n",a[i]);
}
ll M = 999911658;
ll ans = 0;
for(int i = 1;i <= 4;++i) {
ans += a[i] * (M / b[i]) % M * qm(M / b[i],b[i] - 2,b[i]) % M;
ans %= M;
}
cout<<qm(G,ans,M + 1);
return 0;
}
===================================================================================
该怎麼去形容为思念酝酿的痛
夜空霓虹都是我不要的繁荣 ===================================================================================