参考知识链接

 

关于枚举旋转置换:

  前两题都是枚举了 n 种旋转, 但这个可以优化到\(O(\sqrt{n})\) (这个其实是基本操作). 考虑到每个循环节的长度都是 n 的因数, 所以可以枚举 n 的因数, 再乘以这个因数的贡献, 即被计算了几次, 对于一个数 a, 如果gcd(a, n) == d, 那么 a 就对 d 产生了 1 次贡献, 而一共有\(\varphi{(n/d)}\)个这样的数.

 

POJ 2409

题意: 有一串 s 个珠子的项链, 每个珠子的颜色有 c 种, 经过旋转和轴对称变换后相等的项链是视为相同的, 问有多少种项链.

思路: 旋转次数有[0, s - 1] 共 s 种, 对称操作分奇偶讨论, 不过都是 n 种, 然后用 Pólya 定理计算结果.

view code
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define ll long long int c, s; inline ll ksm(ll a, ll n) {
ll r = 1;
while (n) {
if (n & 1) r = r * a;
a = a * a;
n >>= 1;
}
return r;
} int gcd(int x, int y) {
if (y == 0) return x;
return gcd(y, x % y);
} int main() {
while (scanf("%d %d", &c, &s) != EOF && c) {
ll res = ksm((ll)c, (ll)s); // 0
for (int i = 1; i < s; i++) {
res += ksm((ll)c, (ll)gcd(i, s));
}
if (s & 1)
res += s * ksm((ll)c, (s + 1) / 2);
else
res += (c + 1) * s / 2 * ksm((ll)c, s / 2);
printf("%lld\n", res / 2 / s);
}
}

 

AOJ 2164

题意: 有两国的大使共 N 人要坐在一个圆周上开会, 不能有连续的 k 个同国的人坐在一起, 问有多少种坐法. N ≤ 1000, k ≤ 1000.

思路: 这题难点在于确定了循环节长度之后, 有多少种合法的坐法. 对于一个循环节, 不妨考虑开头为A, 根据对称性最后把答案乘 2 就是总的情况数. 定义dp_a[i][j], dp_b[i][j]为总长为 i, 结尾有 j 个 A/B, 中间没有连续 k 个同国 (但不考虑首尾相连超过 k, 不然状态数有\(N^3\)种) 的情况数. 需要计算一个合法的循环节时, 分类讨论结尾是A/B: 结尾是A时, 考虑除去开头和结尾后还剩的串长(保证不为0, 否则会重复计数), 此时剩下的串开头和结尾都是B, 它的数量和同长度的开头结尾都是A的串相同! 再乘以出现该剩余串长的次数; 结尾是 B 时, 首尾相连必不连续, dp_b的前缀和即是所求. 最后还有一个特意省略的情况: 全为A, 注意此时不能简单地认为首尾数相加不大于 k 即可, 因为此时整个环都是 A 应该比较 n 与 k.

view code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i, l, r) for (int i = l; i <= r; i++) const int maxn = 1005;
const int mod = 1000003; int n, k;
int dp_a[maxn][maxn], dp_b[maxn][maxn]; //一定以a开头,总长为i, 结尾是j个a/b
int sum_a[maxn], sum_b[maxn]; inline ll ksm(ll a, ll n) {
ll r = 1;
while (n) {
if (n & 1) r = r * a % mod;
a = a * a % mod;
n >>= 1;
}
return r;
} int main() {
while (cin >> n >> k && n) {
memset(dp_a, 0, sizeof(dp_a));
memset(dp_b, 0, sizeof(dp_b));
dp_a[1][1] = 1;
inc(i, 1, n - 1) {
inc(j, 1, min(i, k)) {
if (j + 1 <= k)
dp_a[i + 1][j + 1] =
(dp_a[i + 1][j + 1] + dp_a[i][j]) % mod;
dp_b[i + 1][1] = (dp_b[i + 1][1] + dp_a[i][j]) % mod;
}
inc(j, 1, min(i - 1, k)) {
dp_a[i + 1][1] = (dp_a[i + 1][1] + dp_b[i][j]) % mod;
if (j + 1 <= k)
dp_b[i + 1][j + 1] =
(dp_b[i + 1][j + 1] + dp_b[i][j]) % mod;
}
}
memset(sum_a, 0, sizeof(sum_a));
memset(sum_b, 0, sizeof(sum_b));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= min(i, k); j++) {
sum_a[i] = (sum_a[i] + dp_a[i][j]) % mod;
sum_b[i] = (sum_b[i] + dp_b[i][j]) % mod;
}
}
ll res = 0;
for (int i = 1; i <= n; i++) {
int l = __gcd(i, n);
//循环节长度
for (int j = 2; j <= min(k, l - 1); j++) {
//首尾a之和
res = (res + (j - 1) * sum_a[l - j]) % mod;
}
//结尾b
res = (res + sum_b[l]) % mod;
if (k >= n) res++; //全a
}
printf("%lld\n", res * 2 * ksm((ll)n, mod - 2LL) % mod);
}
}

 

牛客挑战赛34 C 远山的占卜

题意: 给一个长度为 2n 的圆环染色, 一共有 k 种颜色, 经过旋转, 交换对角的点的颜色视为同构, T组数据. 问有多少种染色方案. T ≤ 2222,1 ≤ n, k < 19260817

思路: 这题除了旋转置换, 多出了一个交换对角的点的操作. 这里把对角的两个点视为"一体"的, 这个整体有 k × (k + 1) / 2 种染色方案. 选取连续的半个圆, 相当于对 n 个点进行 k × (k + 1) / 2 染色, 套用Pólya 定理即可.

view code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i, l, r) for (int i = l; i <= r; i++) const int mod = 19260817; int t;
ll n, k; const int maxnum = mod;
int prim[maxnum], pvis[maxnum + 5], pcnt, phi[maxnum + 5]; void getprim() {
phi[1] = 1;
for (int i = 2; i <= maxnum; i++) {
if (!pvis[i]) prim[++pcnt] = i, phi[i] = i - 1;
for (int j = 1; j <= pcnt && (ll)prim[j] * i <= maxnum; j++) {
pvis[prim[j] * i] = 1;
if (i % prim[j] == 0) {
phi[i * prim[j]] = phi[i] * prim[j];
break;
}
phi[i * prim[j]] = phi[i] * (prim[j] - 1);
}
}
} inline ll ksm(ll a, ll n) {
a %= mod;
ll r = 1;
while (n) {
if (n & 1) r = r * a % mod;
a = a * a % mod;
n >>= 1;
}
return r;
} int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
getprim();
cin >> t;
while (t--) {
cin >> n >> k;
k = k * (k + 1) / 2;
vector<int> divs;
for (int i = 1; i <= n / i; i++) {
if (n % i == 0) {
divs.push_back(i);
if (i < n / i) divs.push_back(n / i);
}
}
ll res = 0;
for (int d : divs) {
res = (res + phi[n / d] * ksm(k, (ll)d)) % mod;
}
cout << res * ksm(n, mod - 2LL) % mod << "\n";
}
}

疑惑: 这题我起初是认为交换对角的点也是一种置换, 但是这样子的话样例都解释不了. 未解, 难道说交换对角不属于置换?

 

Polya 定理相关题目的更多相关文章

  1. Burnside引理和Polya定理

    转载自:https://blog.csdn.net/whereisherofrom/article/details/79631703 Burnside引理 笔者第一次看到Burnside引理那个公式的 ...

  2. POJ 2409 Let it Bead:置换群 Polya定理

    题目链接:http://poj.org/problem?id=2409 题意: 有一串n个珠子穿起来的项链,你有k种颜色来给每一个珠子染色. 问你染色后有多少种不同的项链. 注:“不同”的概念是指无论 ...

  3. 【群论】polya定理

    对Polya定理的个人认识     我们先来看一道经典题目:     He's Circles(SGU 294)         有一个长度为N的环,上面写着“X”和“E”,问本质不同的环有多少个(不 ...

  4. POJ 2409 Let it Bead(Polya定理)

    点我看题目 题意 :给你c种颜色的n个珠子,问你可以组成多少种形式. 思路 :polya定理的应用,与1286差不多一样,代码一改就可以交....POJ 1286题解 #include <std ...

  5. POJ 1286 Necklace of Beads(Polya定理)

    点我看题目 题意 :给你3个颜色的n个珠子,能组成多少不同形式的项链. 思路 :这个题分类就是polya定理,这个定理看起来真的是很麻烦啊T_T.......看了有个人写的不错: Polya定理: ( ...

  6. 百练_2409 Let it Bead(Polya定理)

    描述 "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you ca ...

  7. polya定理小结

    polya的精髓就在与对循环节的寻找,其中常遇到的问题就是项链染色类问题. 当项链旋转时有n种置换,循环节的个数分别是gcd(n, i); 当项链翻转时有n种置换,其中当项链珠子数位奇数时,循环节的个 ...

  8. HDU 4633 Who's Aunt Zhang (Polya定理+快速幂)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4633 典型的Polya定理: 思路:根据Burnside引理,等价类个数等于所有的置换群中的不动点的个 ...

  9. [bzoj1488][HNOI2009]图的同构——Polya定理

    题目大意 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b ...

随机推荐

  1. mysql 存储过程 执行存储过程修改了表中所有行的信息

    存储过程中的where条件语句,如果传入的参数和表字段名相同,存储过程就会把这个约束条件忽略.小结:存储过程中传递的参数名不要和字段名相同.特别是修改.删除等操作,可能会对整张表产生影响.后果会很严重 ...

  2. 教你如何使用css隐藏input的光标

    今天公司的ui突然跑过来问我一个问题:"如何在不影响操作的情况下,把input的光标隐藏了?". 我相信很多人会跟我一样,觉得这是个什么狗屁需求,输入框不要光标这不是反人类吗?可惜 ...

  3. 前端每日实战:152# 视频演示如何用纯 CSS 创作一个圆点错觉效果

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/gBwzKR 可交互视频 此视频是可 ...

  4. AJAX 的 Ajax返回数据之前的loading等待效果(gif效果等)

    首先,我们通过ajax请求,向后台传递参数,然后后台经过一系列的运算之后向前台返还数据,我希望在等待数据成功返还之前可以展示一个loading.gif图 不废话,在页面上执行点击事件(<a sc ...

  5. Vue+axios(interceptors) 实现http拦截 + router路由拦截 (双拦截)+ 请求自带loading效果

    axios interceptors 拦截器 //interceptors.js // vue axios配置 发起请求加载loading请求结束关闭loading // http request 请 ...

  6. href="#"和href=“javascript:void(0)”的区别

    void是javascript中的关键字,该操作符指定要计算一个表达式但是不返回值. <a href="javascript:void(0);">点我没有反应的!< ...

  7. RTP SIP win服务端软件 VOIP

    RTP Real-time Transport Protocol 实时传输入协议,使用 udp 做为载体. SIP Session Initiation Protocol 会话初始化协议,加入,查询, ...

  8. isEmpty 判空函数 内部分别判断是 null 空数组 等

    import { oneOf, isEmpty } from '@/libs/tools' export const isEmpty = (value) => { if (value == nu ...

  9. Pending 打断点

    pending 英['pendɪŋ],美['pɛndɪŋ] a. 未决定的, 待决的, 行将发生的, 向外伸出的prep. 在等待...之际, 直到...时为止, 在...期间, 在...过程中 pe ...

  10. ASP.NET MVC5实现芒果分销后台管理系统(一):系统结构设计,集成AutoMapper,Log4net

    在构思完系统思维脑图后,小墨回到家中,便摩拳擦掌开始了开发工作.要想迅速完成系统开发,前期系统设计和准备尤其重要,因为小墨做过太多大大小小的业务系统,准备工作也是十分顺利. 系统结构 整个系统工程结构 ...