• Codeforces 935D Fafa and Ancient Alphabet


    题目链接

    题意

    给定两个(n)位的(m)进制数(s1,s2),所有出现的(0)均可等概率地被其他数字替换,求(s1gt s2)的概率。

    思路

    从高位到低位,根据每一位上相应的(0)的个数进行 分类讨论

    计算每一位的时候加上这样一部分答案:比到该位恰能比出大小的情况数。

    恰能比出大小意味着:高位全部相同,该位(s1gt s2),低位随便怎么取。

    因此,需对两个数目进行记录:1. 前面有多少位是两者皆0;2. 后面还有多少个0没有确定。

    另:(x)关于(mod)的乘法逆元为(x^{(mod-2)}),由费马小定理易得。

    注意:要对(m)的幂次进行预处理。

    Code

    #include <bits/stdc++.h>
    #define maxn 100010
    #define F(i, a, b) for (int i = (a); i < (b); ++i)
    #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
    #define dF(i, a, b) for (int i = (a); i > (b); --i)
    #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
    using namespace std;
    typedef long long LL;
    const LL mod = 1e9+7;
    int a[maxn], b[maxn];
    LL rec[maxn*2];
    LL poww(LL a, LL b) {
        LL ret = 1;
        while (b) {
            if (b&1) (ret *= a) %= mod;
            (a *= a) %= mod;
            b >>= 1;
        }
        return ret;
    }
    LL f(LL p, LL q) {
        return p * poww(q, mod-2) % mod;
    }
    LL GCD(LL a, LL b) { return b ? GCD(b, a%b) : a; }
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        LL NUM = (1LL*m*m%mod-m+mod)%mod * poww(2, mod-2) % mod;
        int tot=0;
        F(i, 0, n) { scanf("%d", &a[i]); if (!a[i]) ++tot; }
        F(i, 0, n) { scanf("%d", &b[i]); if (!b[i]) ++tot; }
        rec[0] = 1;
        F2(i, 1, tot) rec[i] = rec[i-1]*m%mod;
        LL q = poww(m, tot), p=0;
        int cnt=0, prev=0;
        F(i, 0, n) {
            if (a[i]&&b[i]) {
                if (a[i]>b[i]) (p += rec[cnt+tot-prev]) %= mod;
                if (a[i]!=b[i]) { printf("%I64d
    ", f(p, q)); return 0; }
            }
            else if (!a[i] && !b[i]) {
                prev += 2;
                (p += (rec[cnt+tot-prev] * NUM % mod)) %= mod;
                ++cnt;
            }
            else {
                ++prev;
                if (a[i]) (p += rec[cnt+tot-prev] * (a[i]-1) % mod) %= mod;
                else (p += (rec[cnt+tot-prev] * (m-b[i]) % mod)) %= mod;
            }
        }
        LL gcd = GCD(p, q);
        p /= gcd, q /= gcd;
        printf("%I64d
    ", f(p, q));
        return 0;
    }
    
    
  • 相关阅读:
    【转】P2P通信原理与实现(C++)
    【转】P2P通信标准协议(二)之TURN
    【转】P2P之UDP穿透NAT的原理与实现
    【转】P2P的原理和常见的实现方式
    【转】linux中man使用技巧
    【转】go编译时,加入svn版本信息
    各种移动GPU压缩纹理的使用方法
    Unity贴图压缩格式设置
    关于U3D贴图格式压缩
    可能会导致.NET内存泄露的8种行为
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/8460498.html
Copyright © 2020-2023  润新知