美文网首页
BZOJ_1004 Cards

BZOJ_1004 Cards

作者: Zhu8655 | 来源:发表于2015-05-16 17:19 被阅读58次

    1.题目相关

    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)] mod p
    所以原式等于
    (a/b) % p

    • 而 k 的值只要调用一下 exgcd 就好了。但需注意接出来 k 可能是负数,所以要不断加 p 。
    • 代码如下
    exgcd(b, p, k, y);
    while (k <= 0) k += p;
    
    • 注意题目中有一个比较坑爹的一个地方:没有(1,2,3...n-1,n)这个置换。其实还是我太菜

    点击查看代码

    相关文章

      网友评论

          本文标题:BZOJ_1004 Cards

          本文链接:https://www.haomeiwen.com/subject/guskqttx.html