@hdu - 6427@ Problem B. Beads
@description@
有 m 种不同颜色的珠子,颜色分别为 1~m,每一种颜色的珠子有任意多个。你需要从中选出 n 个珠子构成一个项链。
如果经过任意次以下的操作后项链 A 变为了 B,我们就认为 A 与 B 等价。
(1)将项链旋转。
(2)将项链翻转。
(3)同时将项链上的每一颗珠子替换成它的下一种颜色,颜色 i 将被替换为 i mod m + 1。
求最后不同的项链的个数。
Input
第一行一个整数 T 表示数据组数。
对于每组数据包含两个整数 n, m,描述了项链长度以及颜色个数。
1 ≤ T ≤ 20, 3 ≤ n ≤ 10^18, 2 ≤ m ≤ 10^18, 998244353 不整除 n, m
Output
对于每组数据,输出答案模 998244353.
Sample Input
5
3 2
4 2
8 5
9 5
2333 333
Sample Output
2
4
5079
22017
544780894
Hint
对于 n = 3, m = 2:
- [1, 1, 1], [2, 2, 2] 等价
- [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2, 1], [2, 1, 2], [1, 2, 2] 等价
@solution@
较为典型的 burnside 引理计数问题。
首先我们将颜色全部减一,变为 0~m-1 之间的颜色。这样就可以直接取模。
题目中的操作可以分为两类:位移操作和颜色操作。
其中位移操作就是经典的旋转 + 翻转问题,构成置换群 G1,G1 包含 2*n 个置换。
而颜色操作构成的群 G2 中共含有 m 个置换,对应的操作分别为将颜色 i 变为 i, (i+1) mod m, (i+2) mod m, ...。
对于一个项链的置换可以由一个位移置换套上一个颜色置换组成,令这个置换群为 G3,则有 |G3| = |G1|*|G2| = 2*n*m。
考虑在一个位移置换与一个颜色置换嵌套的情况下不动点的个数。
类比 polya 定理,我们考虑位移置换形成的循环中染色的方案数,再将所有循环的方案数相乘。
假设一个循环为 (a1, a2, a3, ... ak),如果要在颜色变化量为 d 的情况下相同,则要满足 a1 + d = a2, a2 + d = a3, ..., ak + d = a1(这里的“加法”被重新定义模意义下的加法)。
所以有 k*d = 0 mod m。因为 d 是一个 0~m-1 之间的数,所以 d 的取值共有 gcd(m, k) 种。
注意 d 的取值要对每个循环都要满足,对于旋转每个循环大小一样所以不重要,但是翻转可能同时存在大小为 1 和 2 的循环。
如果位移是翻转,可以直接分类讨论出来。
如果位移是旋转,需要枚举 n 的因子作为循环的大小,算出对应的欧拉函数计算贡献。
然后因为 n 很大,所以需要 pollard-rho 加速分解因数的过程。
@accepted code@
#include<map>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
typedef long long ll;
const int MOD = 998244353;
const int PRM[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
map<ll, int>mp;
int pow_mod(int b, int p) {
int ret = 1;
while( p ) {
if( p & 1 ) ret = 1LL*ret*b%MOD;
b = 1LL*b*b%MOD;
p >>= 1;
}
return ret;
}
ll gcd(ll a, ll b) {return (b == 0) ? a : gcd(b, a%b);}
ll mul_mod(ll a, ll b, ll mod) {
a %= mod, b %= mod;
ll ret = 0;
while( b ) {
if( b & 1 ) ret = (ret + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return ret;
}
ll pow_mod(ll b, ll p, ll mod) {
ll ret = 1;
while( p ) {
if( p & 1 ) ret = mul_mod(ret, b, mod);
b = mul_mod(b, b, mod);
p >>= 1;
}
return ret;
}
bool Miller_Rabin(ll n, ll m, int a) {
if( n == a ) return true;
else if( n % a == 0 ) return false;
ll x = pow_mod(a, m, n);
if( x == 1 || x == n-1 )
return true;
while( m != n-1 ) {
x = mul_mod(x, x, n), m *= 2;
if( x == 1 ) return false;
else if( x == n-1 ) return true;
}
return false;
}
bool IsPrime(ll n) {
ll m = n-1;
while( m % 2 == 0 ) m /= 2;
for(int i=0;i<10;i++)
if( !Miller_Rabin(n, m, PRM[i]) )
return false;
return true;
}
ll PollardRho(ll n) {
if( n == 1 ) return n;
if( n % 2 == 0 ) return 2;
ll x = rand() % (n-2) + 2, y = x;
ll c = rand() % (n-1) + 1, d = 1;
while( d == 1 ) {
x = (mul_mod(x, x, n) + c) % n;
y = (mul_mod(y, y, n) + c) % n;
y = (mul_mod(y, y, n) + c) % n;
d = gcd(n, x > y ? x-y : y-x);
}
return d;
}
void GetDiv(ll x) {
if( x == 1 ) return ;
if( IsPrime(x) )
mp[x]++;
else {
ll k = PollardRho(x);
GetDiv(k), GetDiv(x/k);
}
}
int ans; ll n, m;
vector<pair<ll, int> >d;
void dfs(int x, ll nw, ll phi) {
if( x == d.size() ) {
ans = (ans + 1LL*(gcd(m, nw)%MOD)*pow_mod((m%MOD), (n/nw)%(MOD-1))%MOD*(phi%MOD)%MOD)%MOD;
return ;
}
dfs(x + 1, nw, phi);
nw *= d[x].first, phi *= d[x].first - 1;
dfs(x + 1, nw, phi);
for(int i=2;i<=d[x].second;i++) {
nw *= d[x].first, phi *= d[x].first;
dfs(x + 1, nw, phi);
}
}
void solve() {
scanf("%lld%lld", &n, &m);
mp.clear(), d.clear(), GetDiv(n);
for(map<ll, int>::iterator it=mp.begin();it!=mp.end();it++)
d.push_back(*it);
ans = 0; dfs(0, 1, 1);
if( n & 1 )
ans = (ans + (n%MOD)*pow_mod((m%MOD), ((n+1)/2)%(MOD-1))%MOD)%MOD;
else {
ans = (ans + ((n/2)%MOD)*pow_mod((m%MOD), (n/2)%(MOD-1))%MOD*gcd(2, m)%MOD)%MOD;
ans = (ans + ((n/2)%MOD)*pow_mod((m%MOD), (n/2+1)%(MOD-1))%MOD)%MOD;
}
printf("%lld\n", 1LL*ans*pow_mod((2*n%MOD)*(m%MOD)%MOD, MOD-2)%MOD);
}
int main() {
srand(20041112);
int T; scanf("%d", &T);
for(int i=1;i<=T;i++) solve();
}
@details@
算是中档难度的经典题吧。写起来也没有什么特别需要注意的细节。
@hdu - 6427@ Problem B. Beads的更多相关文章
- hdu 1817 Necklace of Beads(Polya定理)
Necklace of Beads Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 6343.Problem L. Graph Theory Homework-数学 (2018 Multi-University Training Contest 4 1012)
6343.Problem L. Graph Theory Homework 官方题解: 一篇写的很好的博客: HDU 6343 - Problem L. Graph Theory Homework - ...
- hdu 1817 Necklace of Beads (polya)
Necklace of Beads Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- hdu String Problem(最小表示法入门题)
hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include &l ...
- HDU 6343 - Problem L. Graph Theory Homework - [(伪装成图论题的)简单数学题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6343 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU 5687 Problem C 【字典树删除】
传..传送:http://acm.hdu.edu.cn/showproblem.php?pid=5687 Problem C Time Limit: 2000/1000 MS (Java/Others ...
- HDU 6342.Problem K. Expression in Memories-模拟-巴科斯范式填充 (2018 Multi-University Training Contest 4 1011)
6342.Problem K. Expression in Memories 这个题就是把?变成其他的使得多项式成立并且没有前导零 官方题解: 没意思,好想咸鱼,直接贴一篇别人的博客,写的很好,比我的 ...
- HDU 6336.Problem E. Matrix from Arrays-子矩阵求和+规律+二维前缀和 (2018 Multi-University Training Contest 4 1005)
6336.Problem E. Matrix from Arrays 不想解释了,直接官方题解: 队友写了博客,我是水的他的代码 ------>HDU 6336 子矩阵求和 至于为什么是4倍的, ...
- HDU 5687 Problem C(Trie+坑)
Problem C Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Tota ...
随机推荐
- Django中的orm的惰性机制
惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象)[https://www.cnblogs.com/chaojiying ...
- win10 下安装 neo4j
1.neo4j介绍 neo4j是基于Java语言编写图形数据库.图是一组节点和连接这些节点的关系.图形数据库也被称为图形数据库管理系统或GDBMS.详细介绍可看Neo4j 教程 2.安装Java jd ...
- Win7。56个进程让我头疼
乱七八糟的进程一个一个往外蹦,如此痛苦. 安装了一个VM9,进程数量+5,安装了卖咖啡的,进程数量+5. 除去这10个,系统进程数量还有46个....还是太多... 64位系统,真的很痛苦,还没有怎么 ...
- 说说a标签的onclick和href
在平时我们一般会在列表中的最后一列给加上操作功能,一般的操作功能是修改和删除,这个操作我们可以通过a标签来实现其功能. <a class="pn-opt" href=&quo ...
- DX9纹理半像素偏移-Directly Mapping Texels to Pixels
原文:DX9纹理半像素偏移-Directly Mapping Texels to Pixels 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u01 ...
- oracle 写存储过程有返回值时 注意在loop循环处添加返回值:=
例子: create or replace procedure p_xl is v_count NUMBER(10); begin for rs in(select yhbh from dbyh) l ...
- day38 21-今天的内容总结
以前我们在web层里面去调Service再在Service里面去调DAO是一路new过去的,在web层里面new Service,然后在Service里面new DAO.每次你都需要主动去找这个对象. ...
- NOIP模拟 7.04
魔术球问题弱化版(ball.c/.cpp/.pas) [题目描述] 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. ( ...
- 移动web的基础知识
一.像素 px:CSS pixels逻辑像素,浏览器使用的抽象单位 dp,pt:设备无关像素 (物理像素) dpr:设备像素缩放比 计算公式: 1px = (dpr)*(dpr)*dp 二.viewp ...
- svn upgrade
在我们把我们服务器上的svn 版本号升级以后,我们之前的代码再执行svn命令时,会提示需要执行svn upgrade命令把当前的代码由低版本的svn 上迁移到高版本的svn 上去. 直接执行svn u ...