解:先推一个式子,然后就是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的更多相关文章

  1. [武汉集训] Cliquers

    题意 设把\(n\)个不同元素分成若干个大小相等的集合的方案个数为\(res\),求\(m^{res}\)模\(10^9-401\)后的余数. (n,m不超过2*10^9) 分析 可以知道,所求答案为 ...

  2. BZOJ3501 : PA2008 Cliquers Strike Back

    \[\begin{eqnarray*}ans&=&m^{\sum_{i=1}^n Stirling2(n,i)\bmod 999999598}\bmod 999999599\\& ...

  3. 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 ...

  4. bzoj 3501 PA2008 Cliquers Strike Back——贝尔数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3501 用贝尔三角形 p^2 地预处理 p 以内的贝尔数.可以模(mod-1)(它是每个分解下 ...

  5. bzoj 3501 PA2008 Cliquers Strike Back —— 贝尔数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3501 用贝尔三角预处理贝尔数,拆模数并在 \( p \) 进制下使用公式,因为这样每次角标增 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. ABP+AdminLTE+Bootstrap Table权限管理系统第六节--abp控制器扩展及json封装以及6种处理时间格式化的方法

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 一,控制器AbpController 说完了Swagger ui 我们再来说一下abp对控制器的处理和json的封 ...

  2. linux下文件加密方法总结

    为了安全考虑,通常会对一些重要文件进行加密备份或加密保存,下面对linux下的文件加密方法做一简单总结: 方法一:gzexe加密这种加密方式不是非常保险的方法,但是能够满足一般的加密用途,可以隐蔽脚本 ...

  3. linux下syslog-ng日志集中管理服务部署记录

    syslog是Linux系统默认的日志守护进程,默认的syslog配置文件是/etc/syslog.conf文件.syslog守护进程是可配置的,它允许人们为每一种类型的系统信息精确地指定一个存放地点 ...

  4. Centos7.5部署MySQL5.7基于GTID主从复制+并行复制+半同步复制+读写分离(ProxySQL) 环境- 运维笔记 (完整版)

    之前已经详细介绍了Mysql基于GTID主从复制的概念,原理和配置,下面整体记录下MySQL5.7基于GTID主从复制+并行复制+增强半同步复制+读写分离环境的实现过程,以便加深对mysql新特性GT ...

  5. WinForm多线程+委托防止界面假死

    当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决 using System; using System.Collections.Generic ...

  6. 《linux内核设计与实现》读书笔记——第三章

  7. HTTP基础与Android之(安卓与服务器通信)——使用HttpClient和HttpURLConnection

    查看原文:http://blog.csdn.net/sinat_29912455/article/details/51122286 1客户端连接服务器实现内部的原理 GET方式和POST方式的差别 H ...

  8. ☆C++学习心得

    C++是我进大学的学的第一种编程语言,在高中的时候有电脑课,有教过部分的VB语言,所以其实对编程也并不是非常的陌生,刚开是上课也觉得感觉不难,都懂,没多少课后,恍了个神..居然听不懂了!老师经常让我们 ...

  9. LeetCode 363:Max Sum of Rectangle No Larger Than K

    题目链接 链接:https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k/description/ 题解&代码 1 ...

  10. Failed while installing JAX-RS (REST Web Services) 1.1. org.osgi.service.prefs.BackingStoreException: Resource '/.settings' does not exist.

    https://issues.jboss.org/browse/JBIDE-10039?_sscc=t https://stackoverflow.com/questions/16836832/fai ...