您的位置:首页 > 其它

BZOJ_1004 Cards

2015-06-01 17:36 176 查看

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 。

代码如下

exgcd(b, p, k, y);
while (k <= 0) k += p;


注意题目中有一个比较 坑爹 的一个地方:没有(1,2,3…n-1,n)这个置换。其实还是我太菜

点击查看代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: