1.题目相关
- 标签:
Polya
- 题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1004
- 题目大意:中文题。
2.思路
比较基础的Polya计数。
利用Burnside引理+K背包+乘法逆元。居然不经意间就会了K背包
前面两个网上书上资料很多,重点讲乘法逆元。
先讲一下扩展欧几里得。设
a⋅X1+b⋅Y1=gcd(a,b)
b⋅X2+(a%b)⋅Y2=gcd(b,a%b)其中
gcd(a,b)=gcd(b,a%b) , a%b=a−(a/b)⋅b整理可得
a⋅X1+b⋅Y1=b⋅X2+(a−(a/b)⋅b)⋅Y2
a⋅X1+b⋅Y1=a⋅Y2+b⋅[X2−(a/b)]⋅Y2所以
X1=Y2 , Y1=X2−(a/b)⋅Y2代码如下
void exgcd(int a, int b, int &x, int &y) {
if (b == 0) {x = 1; y = 0; return;}
exgcd(b, a%b, x, y);
int t = x; x = y; y = t-a/b*y;
}
有了以上的知识就可以来讨论有关 (a/b) % p 的值的问题了
先来看定义:
满足 a⋅k≡1 (mod p) 的 k 值就是a 关于 p 的乘法逆元。
为什么要用乘法逆元呢?
当我们要求(a/b) % p 的值,且 a 很大,无法直接求得a/b 的值时,我们就要用到乘法逆元。
我们可以通过求 b 关于p 的乘法逆元 k ,将a 乘上 k 再模p ,即 (a⋅k) % p 。其结果与 (a/b) mod p 等价。-
证明如下
根据
b⋅k≡1 (mod p)可得
b⋅k=p⋅x+1
k=(p⋅x+1)/b把 k 代入
(a⋅k) mod p得原式
=(a⋅(p⋅x+1)/b) % p
=((a⋅p⋅x)/b+a/b) % p
=[((a⋅p⋅x)/b) % p+(a/b)] % p所以原式等于
(a/b) % p而 k 的值只要调用一下 exgcd 就好了。但需注意接出来
k 可能是负数,所以要不断加 p <script type="math/tex" id="MathJax-Element-35">p</script> 。- 代码如下
exgcd(b, p, k, y);
while (k <= 0) k += p;
- 注意题目中有一个比较
坑爹的一个地方:没有(1,2,3…n-1,n)这个置换。其实还是我太菜