Processing math: 100%

【BZOJ1951】[SDOI2010]古代猪文

【BZOJ1951】[SDOI2010]古代猪文

题面

bzoj

洛谷

题解

题目实际上是要求

Gd|nCdnmod999911659

而这个奇怪的模数实际上是个素数,由欧拉定理

Gd|nCdnmod999911659=Gd|nCdnmod99911658mod999911659

主要是解决

d|nCdnmod999911658

注意到

999911658=2×3×4679×35617

所以可以对每个质因数枚举约束,用Lucas求组合数

最后CRT合并即可,注意要特判

代码

#include <iostream> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <cmath> 
#include <algorithm> 
using namespace std;
typedef long long ll; 
const ll Mod = 999911658;
ll N, G, fac[50005], ans[10], b[10] = {0, 2, 3, 4679, 35617}; 
ll fpow(ll x, ll y, ll p) {
	ll res = 1;
	while (y) {
		if (y & 1ll) res = res * x % p; 
		x = x * x % p;
		y >>= 1ll; 
	}
	return res; 
} 
void init (ll p) { fac[0] = 1; for (ll i = 1; i <= p; i++) fac[i] = i * fac[i - 1] % p; }
ll C(ll n, ll m, ll p) {
	if (n < m) return 0;
	return fac[n] * fpow(fac[m], p - 2, p) % p * fpow(fac[n - m], p - 2, p) % p; 
} 
ll Lucas(ll n, ll m, ll p) {
	if (!m || !n) return 1; 
	return Lucas(n / p, m / p, p) * C(n % p, m % p, p) % p; 
} 
ll CRT() {
	ll res = 0; 
	for (int i = 1; i <= 4; i++)
		res = (res +
			   ans[i] * (Mod / b[i]) % Mod *
			   fpow(Mod / b[i], b[i] - 2, b[i])
			   % Mod) % Mod;
	return res; 
} 
int main () {
	cin >> N >> G;
	if (G % (Mod + 1) == 0) return puts("0") & 0; 
	for (int p = 1; p <= 4; p++) {
		init(b[p]);
		for (int i = 1; i * i <= N; i++) { 
			if (N % i == 0) {
				ans[p] = (ans[p] + Lucas(N, i, b[p])) % b[p];
				if (i * i != N) ans[p] = (ans[p] + Lucas(N, N / i, b[p])) % b[p]; 
			}
		} 
	} 
	printf("%lld\n", fpow(G, CRT(), Mod + 1)); 
	return 0; 
} 

C++

 

posted @   heyujun  阅读(262)  评论(1编辑  收藏  举报
编辑推荐:
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
阅读排行:
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 2025成都.NET开发者Connect圆满结束
点击右上角即可分享
微信分享提示