Solution -「JZOJ #5457」项链
\(\mathscr{Description}\)
给定一条有 \(n\) 个点的圆环和 \(m\) 中颜色, 求在位置旋转, 位置翻转, 颜色旋转等价的意义下, 本质不同的染色方案数.
数据组数 \(T\le20\), \(n,m\le10^{18}\).
\(\mathscr{Solution}\)
颜色旋转 ... 那么它就不是颜色了, 就用 Burnside 就行.
首先需要明确的是, 我们的变换群长什么样子. 以 \(n=4,m=3\) 的情况为例:
G &= (\{
\iota_4,
\begin{pmatrix}4&1&2&3\end{pmatrix},
\begin{pmatrix}3&4&1&2\end{pmatrix},
\begin{pmatrix}2&3&4&1\end{pmatrix}
\} \\ &\cup\{
\iota_4,
\begin{pmatrix}2&1&4&3\end{pmatrix},
\begin{pmatrix}3&2&1&4\end{pmatrix},
\begin{pmatrix}4&3&1&2\end{pmatrix}
\})\\
&\times \{
\iota_3,
\begin{pmatrix}3&1&2\end{pmatrix},
\begin{pmatrix}2&3&1\end{pmatrix}
\}.
\end{aligned}
\]
第一组是位置旋转, 第二组是位置对称翻转, 第三组是颜色旋转, \(\times\) 是笛卡尔积.
Burnside, 考虑不动点. 假设某个 (位置, 颜色) 的映射对为 \((\varphi_p,\varphi_c)\), 位置 \(x\) 的颜色为 \(c(x)\), 那么不动点需要满足 \(\varphi_c(c(x))=c(\varphi_p(x))\). 先来研究 \(\varphi_p\) 是旋转置换的情况. 通过一些形象的观察可以发现, 设 \(\varphi_p\) 的轮换大小为 \(l_1\), \(\varphi_c\) 的轮换大小为 \(l_2\), 则不动点存在当且仅当 \(l_2\mid l_1\). 此时对于 \(\varphi_p\) 的一个环, 只要确定其中一个位置的颜色, 就可以根据 \(\varphi_c(c(x))=c(\varphi_p(x))\) 唯一确定环上其他点的颜色, 此时环的方案数为 \(m\).
因此, 枚举 \(l_1,l_2\), 我们可以得到 \(\varphi_p\) 是旋转置换时的不动点总数 (式子里的 \(\varphi\) 是欧拉函数 w):
\textit{ans}_1 &= \sum_{l_1\mid n}\varphi(l_1)\sum_{l_2\mid m,l_2\mid l_1}\varphi(l_2)m^{n/l_1}\\
&= \sum_{l_1\mid n}\varphi(l_1)m^{n/l_1}\gcd(m,l_1).
\end{aligned}
\]
此后, 对于对称置换的 \(\textit{ans}_2\), 需要讨论一下奇偶性:
- \(2\nmid n\), 此时所有置换的都有一个 \(l_1=1\) 的轮换, 因此 \(l_2=1\). 总不动点数为 \(n\cdot m^{(n+1)/2}\).
- \(2\mid n,2\nmid m\), 当对称轴放在两个点上时, 和前一种一样, 总不动点数为 \(n/2\cdot m^{n/2+1}\); 当对称轴放在两对点中间时, 所有 \(l_2=2\), 但是 \(2\nmid m\), 所以还是有 \(l_2=1\), 总不动点数为 \(n/2\cdot m^{n/2}\).
- \(2\mid n,2\mid m\), 当对称轴放在两个点上时还是 \(n/2\cdot m^{n/2+1}\); 当对称轴放在两对点中间时, \(l_2\) 可以取 \(1\) 或 \(2\), 总不动点数为 \(n/2\cdot m^{n/2}+n/2\cdot m^{n/2}\).
置换群大小为 \(2nm\), 所以答案为 \((\textit{ans}_1+\textit{ans}_2)/(2nm)\). 计算上需要 Pollard-Rho, 精细处理 \(\gcd\), 顺便预处理 \(m\) 的光速幂, 可以做到 \(\mathcal O(d(n))\).
\(\mathscr{Code}\)
/*+Rainybunny+*/
// #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
typedef long long LL;
typedef std::unordered_map<LL, int> MType;
typedef MType::iterator IType;
#define fi first
#define se second
const int MOD = 998244353;
int ans;
LL n, m;
namespace Factor {
inline LL add(LL u, const LL v, const LL m) {
return (u += v) < m ? u : u - m;
}
inline LL mul(const LL u, const LL v, const LL m) {
return __int128(u) * v % m;
}
inline LL mpow(LL u, LL v, LL m) {
LL ret = 1;
for (; v; u = mul(u, u, m), v >>= 1) ret = mul(ret, v & 1 ? u : 1, m);
return ret;
}
inline LL gcd(const LL u, const LL v) { return v ? gcd(v, u % v) : u; }
inline LL labs(const LL u) { return u < 0 ? -u : u; }
inline bool millerRabin(const LL x, const LL b) {
LL k = x - 1; while (!(k & 1)) k >>= 1;
static LL pwr[70]; pwr[0] = 1, pwr[1] = mpow(b, k, x);
while (k != x - 1) {
pwr[pwr[0] + 1] = mul(pwr[pwr[0]], pwr[pwr[0]], x);
++pwr[0], k <<= 1;
}
per (i, pwr[0], 1) {
if (pwr[i] != 1 && pwr[i] != x - 1) return false;
if (pwr[i] == x - 1) return true;
}
return true;
}
inline bool isprime(const LL x) {
if (x == 2 || x == 3 || x == 5 || x == 7 || x == 11) return true;
if (x == 61 || x == 127) return true;
if (!(x % 2) || !(x % 3) || !(x % 5) || !(x % 7) || !(x % 11))return false;
if (!(x % 61) || !(x % 127)) return false;
return millerRabin(x, 2) && millerRabin(x, 61) && millerRabin(x, 127);
}
inline LL pollardRho(const LL x) {
static std::mt19937 emt(time(0) ^ 20120712);
for (LL a = emt() % (x - 1) + 1, len = 1, st = 0, ed = 0; ;
len <<= 1, st = ed) {
LL prd = 1;
rep (stp, 1, len) {
prd = mul(prd, labs(st - (ed = add(mul(ed, ed, x), a, x))), x);
if (!(stp & 127) && gcd(prd, x) > 1) return gcd(prd, x);
}
if (gcd(prd, x) > 1) return gcd(prd, x);
}
}
inline void factor(LL x, MType& res, const int k = 1) {
if (x == 1) return ;
if (isprime(x)) return void(res[x] += k);
LL d = pollardRho(x); int cnt = 0;
while (!(x % d)) x /= d, ++cnt;
factor(x, res, k), factor(d, res, k * cnt);
}
} // namespace Factor
inline int mul(const int u, const int v) { return 1ll * u * v % MOD; }
inline void subeq(int& u, const int v) { (u -= v) < 0 && (u += MOD); }
inline int sub(int u, const int v) { return (u -= v) < 0 ? u + MOD : u; }
inline void addeq(int& u, const int v) { (u += v) >= MOD && (u -= MOD); }
inline int add(int u, const int v) { return (u += v) < MOD ? u : u - MOD; }
inline int mpow(int u, int v) {
int ret = 1;
for (; v; u = mul(u, u), v >>= 1) ret = mul(ret, v & 1 ? u : 1);
return ret;
}
MType buc;
inline int solve(const IType it, const int phi, const LL l) {
if (it == buc.end()) {
return mul(mul(phi, std::__gcd(m, l) % MOD),
mpow(m % MOD, n / l % (MOD - 1)));
}
int ret = 0, tp = phi; LL tl = l;
IType tmp(std::next(it));
rep (i, 0, it->se) {
addeq(ret, solve(tmp, tp, tl));
tp = mul(tp, (it->fi - !i) % MOD), tl *= it->fi;
}
return ret;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%lld %lld", &n, &m), ans = 0;
if (n & 1) {
addeq(ans, mul(n % MOD, mpow(m % MOD, (n + 1 >> 1) % (MOD - 1))));
} else {
addeq(ans, mul((n >> 1) % MOD,
mpow(m % MOD, (n >> 1) % (MOD - 1))));
addeq(ans, mul((n >> 1) % MOD,
mpow(m % MOD, (n / 2 + 1) % (MOD - 1))));
if (~m & 1) {
addeq(ans, mul((n >> 1) % MOD,
mpow(m % MOD, (n >> 1) % (MOD - 1))));
}
}
buc.clear();
Factor::factor(n, buc);
addeq(ans, solve(buc.begin(), 1, 1));
ans = mul(ans, mpow(mul(m % MOD, (n << 1) % MOD), MOD - 2));
printf("%d\n", ans);
}
return 0;
}
Solution -「JZOJ #5457」项链的更多相关文章
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
- Solution -「CF 1342E」Placing Rooks
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...
- Solution -「简单 DP」zxy 讲课记实
魔法题位面级乱杀. 「JOISC 2020 Day4」治疗计划 因为是不太聪明的 Joker,我就从头开始理思路了.中途也会说一些和 DP 算法本身有关的杂谈,给自己的冗长题解找借口. 首先,治疗方案 ...
- Solution -「基环树」做题记录
写的大多只是思路,比较简单的细节和证明过程就不放了,有需者自取. 基环树简介 简单说一说基环树吧.由名字扩展可得这是一类以环为基础的树(当然显然它不是树. 通常的表现形式是一棵树再加一条非树边,把图画 ...
- Solution -「WC 2022」秃子酋长
\(\mathscr{Description}\) Link. (It's empty temporarily.) 给定排列 \(\{a_n\}\),\(q\) 次询问,每次给出 \([l,r ...
- Solution -「JSOI 2019」「洛谷 P5334」节日庆典
\(\mathscr{Description}\) Link. 给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的). \(|S|\le3\time ...
- Solution -「CF 1622F」Quadratic Set
\(\mathscr{Description}\) Link. 求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...
- Solution -「CF 923F」Public Service
\(\mathscr{Description}\) Link. 给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...
随机推荐
- Linux设置显示中文和设置字体
设置中文 一.查看当前使用的系统语言 1.登陆linux系统打开操作终端之后,输入 echo $LANG可以查看当前使用的系统语言.如 echo $LANG 2.查看安装的语言包 查看是否有中文语言包 ...
- K8s之运行时containerd安装和使用
一.containerd 1. 前生今世 很久以前,Docker 强势崛起,以"镜像"这个大招席卷全球,对其他容器技术进行致命的降维打击,使其毫无招架之力,就连 Google 也不 ...
- Exadata系列之配置利器OECA
Oracle Exadata Configuration Assistant (OECA) 是一款简便的配置工具,用于快速生成Exadata系统的推荐配置方案.它根据用户的需求和负载特点,自动推荐合适 ...
- vagrant 中 php 7.2 升级到 php 7.3
在本地用 vagrant 给 php 7.2 升级到 7.3 的时候,直接修改了 box/config.yml里面 php 版本 然后就 vagrant reload --provision 进行重新 ...
- 文本转换利器之Pandoc
Pandoc 简介 如果你需要在不同的文件格式之间相互转换,多半听说或使用过文档转换的瑞士军刀--Pandoc.事实上,不仅人类知道 Pandoc,最近很火的人工智能 ChatGPT 也知道「将 Ma ...
- Golang之开源项目汇总
汇总一些Golang一些开源项目,平常可以多学习一下源码与项目精髓 pocketbase 集成简单, 开箱即用,拥有简介的后台管理面板 该系统内置试试数据库与rest api, Google,gith ...
- Sublime之快捷操作
列举常用的Sublime操作,涉及操作 1.每行默认需要统一添加逗号 1)全选 ctrl + a 2) 组合键 ctrl + shift + l 即可进行操作 (这里是L哦) 之后也可以使用HOME键 ...
- Gitlab:Restoring PostgreSQL database gitlabhq_production ... ERROR: must be owner of extension pg_trgm
Restoring PostgreSQL database gitlabhq_production ... ERROR: must be owner of extension pg_trgm ERRO ...
- 【Amadeus原创】docker安装TOMCAT,并运行本地代码
1,docker 下载tomcat [root@it-1c2d ~]# docker pull tomcat ... [root@it-1c2d ~]# docker images REPOSITOR ...
- 【Amadeus原创】Docker安装wikijs wiki系统
拉取mysql8的镜像并运行 docker pull mysql docker run -d -v /data/mysql/data:/var/lib/mysql -v /data/mysql/con ...