??? cliquers


解:先推一个式子,然后就是CRT了...

那个阶乘怎么求呢?主要是分母可能有0,这时我们把分母的因子p全部提出来,上下次数相减判断即可。
细节颇多......注意在快速幂开始的时候a %= MO是个好习惯。
#include <cstdio>
#include <algorithm> typedef long long LL;
const int N = ;
const LL MO = 1e9 - , mod[] = {, , , , }; int turn;
LL ans[], n, m, nn[][];
//LL inv[10000][5], invn[10000][5]; inline LL qpow(LL a, LL b, LL c) {
LL ans = ;
a %= c;
while(b) {
if(b & ) ans = ans * a % c;
a = a * a % c;
b = b >> ;
}
return ans;
} inline LL Pow(LL a, LL b) {
LL ans = ;
while(b) {
if(b & ) ans = ans * a;
a = a * a;
b = b >> ;
}
return ans;
} LL exgcd(LL a, LL &x, LL b, LL &y) {
if(!b) {
x = ; y = ;
return a;
}
LL g = exgcd(b, x, a % b, y);
std::swap(x, y);
y -= x * (a / b);
return g;
} inline LL getnn(LL x) {
if(!x) return ;
LL t = x / mod[turn];
LL ans = qpow(nn[mod[turn] - ][turn], t, mod[turn]);
t = x % mod[turn];
return ans * nn[t][turn] % mod[turn] * getnn(x / mod[turn]);
} inline LL cal(LL k) { //printf("cal %lld \n", k);
//bool f = (turn == 2 && k == 2) || (turn == 2 && k == 1); LL time = ;
for(LL i = n; i > ; i /= mod[turn]) {
time += i / mod[turn];
//printf("1 time += %lld = %lld \n", i / mod[turn], time);
}
for(LL i = k; i > ; i /= mod[turn]) {
time -= i / mod[turn];
//printf("2 time -= %lld = %lld \n", i / mod[turn], time);
}
for(LL i = n / k; i > ; i /= mod[turn]) {
time -= (i / mod[turn]) * k;
//printf("3 time -= %lld = %lld\n", i / mod[turn], time);
}
if(time) {
//printf(" -- -- return 0 \n");
//printf("mod = %lld ans = 0\n", mod[turn]);
return ;
} LL t1 = getnn(n), t2 = getnn(k), t3 = getnn(n / k);
/*if(f) {
printf("%lld %lld %lld \n", t1, t2, t3);
}*/
t3 = qpow(t3, k, mod[turn]);
t2 = qpow(t2, mod[turn] - , mod[turn]);
t3 = qpow(t3, mod[turn] - , mod[turn]); //printf("return %lld \n", t1 * t2 % mod[turn] * t3 % mod[turn]);
//printf("mod = %lld k = %lld ans = %lld \n", mod[turn], k, t1 * t2 % mod[turn] * t3 % mod[turn]);
return t1 * t2 % mod[turn] * t3 % mod[turn];
} inline LL solve() { /// cal each prime
LL ans = ;
for(LL i = ; i * i <= n; i++) {
if(n % i) continue;
ans = (ans + cal(i)) % mod[turn];
if(i * i < n) {
ans = (ans + cal(n / i)) % mod[turn];
}
}
return ans;
} inline void work() {
scanf("%lld%lld", &n, &m);
//m %= MO; for(turn = ; turn <= ; turn++) {
ans[turn] = solve();
//printf("ans %d %lld = %lld \n", turn, mod[turn], ans[turn]);
} /// excrt
/*LL a = ans[1], p = mod[1];
for(int i = 2; i <= 4; i++) {
/// merge
//printf("merge %d \n", i);
LL P = p * mod[i], x, y;
LL c1 = ((a - ans[i]) % P + P) % P;
//printf("a = %lld c1 = %lld \n", a, c1);
LL g = exgcd(mod[i], x, p, y);
(x *= (c1 / g)) %= P; (y *= (c1 / g)) %= P;
a = (x * mod[i] % P + ans[i]) % P;
p = P;
//printf("merge %lld ans = %lld \n", mod[i], a);
}*/
/// crt
LL a = , p = MO - ;
for(int i = ; i <= ; i++) {
a = (a + ans[i] * (p / mod[i]) % p * qpow(p / mod[i], mod[i] - , mod[i]) % p) % p;
} //printf("over \n");
a = (a % p + p) % p;
//printf("a = %lld\n", a);
LL ans = qpow(m, a, MO);
printf("%lld\n", ans);
return;
} inline void prework() {
for(turn = ; turn <= ; turn++) {
//invn[0][turn] = inv[0][turn]turn] = nn[0][turn] = 1;
nn[][turn] = ;
//invn[1][turn] = inv[1][turn]turn] = nn[1][turn] = 1;
for(int i = ; i < mod[turn]; i++) {
nn[i][turn] = nn[i - ][turn] * i % mod[turn];
//inv[i][turn] = inv[mod[turn] % i] * (mod[turn] - mod[turn] / i) % mod[turn];
//invn[i][turn] = invn[i - 1][turn] * inv[i][turn] % mod[turn];
}
}
return;
} int main() { freopen("cliquers.in", "r", stdin);
freopen("cliquers.out", "w", stdout); prework(); int T;
scanf("%d", &T);
while(T--) {
work();
}
return ;
}
AC代码
两种CRT都写了。
??? cliquers的更多相关文章
- [武汉集训] Cliquers
题意 设把\(n\)个不同元素分成若干个大小相等的集合的方案个数为\(res\),求\(m^{res}\)模\(10^9-401\)后的余数. (n,m不超过2*10^9) 分析 可以知道,所求答案为 ...
- BZOJ3501 : PA2008 Cliquers Strike Back
\[\begin{eqnarray*}ans&=&m^{\sum_{i=1}^n Stirling2(n,i)\bmod 999999598}\bmod 999999599\\& ...
- BZOJ3500 : PA2008 Cliquers
设g[i]表示n=i时的答案,则OEIS上可以找到如下递推式: g[i]=g[i-1]+g[i-2]-g[i-5]-g[i-7]+... 其中符号为++--交替,第i项为f[i],f[1]=1,f[2 ...
- bzoj 3501 PA2008 Cliquers Strike Back——贝尔数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3501 用贝尔三角形 p^2 地预处理 p 以内的贝尔数.可以模(mod-1)(它是每个分解下 ...
- bzoj 3501 PA2008 Cliquers Strike Back —— 贝尔数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3501 用贝尔三角预处理贝尔数,拆模数并在 \( p \) 进制下使用公式,因为这样每次角标增 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- 关于Prometheus运维实践项目
关于Promethues运维实践项目 1. 什么是Prometheus运维实践项目 是什么 Prometheus,普罗米修斯,是古希腊神话中为人间带来火种的神. Prometheus运维实 ...
- java使用何种类型表示精确的小数?
问题 java使用何种类型表示精确的小数? 结论 float和double类型的主要设计目标是为了科学计算和工程计算,速度快,存在精度丢失 BigDecimal用来表示任意精确浮点数运算的类,在商业应 ...
- 暴雪《争霸艾泽拉斯》*采用自适应 SSAO
在实时渲染过程中,屏幕空间环境光遮蔽 (SSAO) 常用于打造小范围环境光效果和接触阴影效果.它用于许多现代游戏,通常占用 5% 到 10% 的帧时间.在<争霸艾泽拉斯>* 游戏开发过程中 ...
- Docker网络解决方案 - Flannel部署记录
Docker跨主机容器间网络通信实现的工具有Pipework.Flannel.Weave.Open vSwitch(虚拟交换机).Calico, 其中Pipework.Weave.Flannel,三者 ...
- Nginx+keepalived 双机热备(主主模式)
之前已经介绍了Nginx+Keepalived双机热备的主从模式,今天在此基础上说下主主模式的配置. 由之前的配置信息可知:master机器(master-node):103.110.98.14/19 ...
- tmux使用总结
ctrl+b +%:增加垂直分屏 ctlr+b +左右箭头: 在垂直分屏中移动 ctrl+b+c:新建窗口(不分屏) ctrl+b+数字键: 切换窗口 ctrl+b+d: 断开窗口 tmux a : ...
- [北航矩阵理论A]课程笔记
[北航矩阵理论A]课程笔记 一.特征值 特征根相关: 设任一方阵 \(A = (a_{ij})_{n\times n} \in C^{n\times n}\) 特征多项式 \(T(\lambda)=| ...
- hover设定触发时间间隔
500毫秒执行一次 $(".banner_menu_content li a").hover(function(){ var aa=$(this).text().trim(); s ...
- Docker for windows 入门三(PowerShell命令使用)
- Linux CentOS7 安装php简要过程以及nginx
Copy From https://www.cnblogs.com/freeweb/p/5425554.html 修改了下: 1. 下载php源码: wget http://cn2.php.net ...