解:先推一个式子,然后就是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. (11)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Thrift高效通讯 (完结)

    一. 什么是 RPC Restful 采用 Http 进行通讯,优点是开放.标准.简单.兼容性升级容易: 缺点是性能略低.在 QPS 高或者对响应时间要求苛刻的服务上,可以用 RPC(Remote P ...

  2. GeForce Experience关闭自动更新

    GeForce Experience驱动更新很烦,而且有时更新后就打不开了,找到种方法关闭更新 1.安装并登陆 2.打开 C:\ProgramData\NVIDIA Corporation 3.进入D ...

  3. if...else 小练习

    # 需求:猜年龄,可以让用户最多猜三次 age = 60 for i in range(3): guess = int(input("Input Age: ")) if guess ...

  4. Tomcat通过Memcached实现session共享的完整部署记录

    对于web应用集群的技术实现而言,最大的难点就是:如何能在集群中的多个节点之间保持数据的一致性,会话(Session)信息是这些数据中最重要的一块.要实现这一点, 大体上有两种方式:一种是把所有Ses ...

  5. Python-复习-文件操作-21

    # 文件处理 # 打开文件 #open('路径','打开方式','指定编码方式') # 打开方式 r w a r+ w+ a+ b #r+ 打开文件直接写 和读完再写 # 编码方式 —— utf-8 ...

  6. 对于VS软件的个人评价

    因为还是一个菜鸟,对于VS这样的大软件还只能是自己个人的理解,以前用的是VC++,后来因为电脑系统更新,开始接触了VS,个人觉得还是vs2010更好用一些,作为一款windows平台应用程序的集成开发 ...

  7. hibernate ehcache二级缓存

    xml配置 <?xml version="1.0" encoding="UTF-8"?> <ehcache> <!-- Sets ...

  8. 探索guava(一)——前置条件Preconditions类

    作用 可以简洁的完成参数检验,在进行业务逻辑代码前进行前置判断.并且避免了冗长的if语句.guava将所有检验的API都放置于Preconditions类中. API Preconditions类大致 ...

  9. Maven修改默认JDK

    Maven修改默认JDK 问题: 1.创建maven项目的时候,jdk版本是1.5版本,而自己安装的是1.7或者1.8版本. 2.每次右键项目名-maven->update project 时候 ...

  10. PAT 1002 写出这个数

    https://pintia.cn/problem-sets/994805260223102976/problems/994805324509200384 读入一个自然数n,计算其各位数字之和,用汉语 ...