Codeforces 935D Fafa and Ancient Alphabet

题目链接

题意

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

思路

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

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

恰能比出大小意味着:高位全部相同,该位\(s1\gt 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\n", 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\n", f(p, q));
    return 0;
}

原文地址:https://www.cnblogs.com/kkkkahlua/p/8460498.html

时间: 2024-08-30 18:35:57

Codeforces 935D Fafa and Ancient Alphabet的相关文章

CF935D Fafa and Ancient Alphabet 概率dp(递推)

D. Fafa and Ancient Alphabet (简洁题意请往下翻) time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Ancient Egyptians are known to have used a large set of symbols  to write on the walls of the temple

Codeforces 935E Fafa and Ancient Mathematics(表达式转树 + 树型DP)

题目链接  Codeforces Round #465 (Div. 2) Problem E 题意  给定一个表达式,然后用$P$个加号和$M$个减号填充所有的问号(保证问号个数等于$P + M$) 求可以形成的表达式的最大值. 先把表达式转成一棵树,然后在树上DP. 题目保证了$min(P, M) <= 100$, 为了提高效率,我们选择用少的运算符号作为DP的第二维. 对$P$和$M$的大小关系进行分类讨论. 当$P < M$时, 设$f[i][j]$表示$i$代表的子树里面填$j$个加号

CF935E Fafa and Ancient Mathematics 树形dp

前言 这是一道cf的比赛题.. 比赛的时候C题因为自己加了一个很显然不对的特判WA了7次但找不出原因就弃疗了... 然后就想划水, 但是只做了AB又不太好... 估计rating会掉惨 (然而事实证明rating一点没变) 就去看看别的题,, 但是英语不好, 看题要看半天, 看看这个E题题目名称像是数论?(mmp估计是受到了古代猪文的影响). 点进去没仔细读题好像是个等价表达式一样的题目? 好像很麻烦还1h不写了(没错C题细节各种挂调了好久好久, 当时已经是很绝望了OvO) 结果这题tm是个dp

Codeforces Round #465

A. Fafa and his Company 方法:暴力枚举leader的个数即可 code: 1 /* 2 by skydog 3 */ 4 #include <iostream> 5 #include <cstdio> 6 #include <vector> 7 #include <utility> 8 #include <algorithm> 9 #include <cmath> 10 #include <cstring

Codeforces Round #465 (Div. 2) ABCD

A. Fafa and his Company Fafa owns a company that works on huge projects. There are n employees in Fafa's company. Whenever the company has a new project to start working on, Fafa has to divide the tasks of this project among all the employees. Fafa f

Codeforces Beta Round #1 C. Ancient Berland Circus

果然Java还是不靠谱啊,一个NaN把我整了半天~~ 题目大意: 有一个正多边形,给出任意三个顶点的坐标,求这个正多边形的最小面积. 解题思路: 首先要知道这三个顶点组成的三角形的外接圆一定是这个正多边形的外接圆. 用过计算出三角形的三边长,可以计算出三角型面积,进而推出外接圆半径. 可以得到三个圆心角,找出最大公约数,那就是最大角度. 就可以计算出多边形面积了~~ 下面是代码: import java.text.DecimalFormat; import java.util.Scanner;

[codeforces 260]B. Ancient Prophesy

试题描述 A recently found Ancient Prophesy is believed to contain the exact Apocalypse date. The prophesy is a string that only consists of digits and characters "-". We'll say that some date is mentioned in the Prophesy if there is a substring in t

Codeforces 611D.New Year and Ancient Prophecy (dp + lcp)

题目链接: http://codeforces.com/problemset/problem/611/D 题意: 长为n的只有数字组成的字符串(n<=5000),问能分割成多少组数字,这些数字里不含前导0,且数字的大小满足严格单调递增 思路: from: http://blog.csdn.net/qwb492859377/article/details/50445450  qwb orz 最难的地方,就是如何去快速判断两个数字的大小谁大谁小呢? 我们先来讲下最长公共前缀lcp的定义.如果有串A和

Codeforces 935 C Fifa and Fafa

935 C 题意:Fifa想用wifi下载足球游戏, 但是Fafa是个流浪狂魔, 所以Fifa想让他的wifi在公寓里尽量覆盖最大的面积,并且不覆盖到Fafa和公寓外的人,fafa的坐标可以在公寓外. 题解:求半径最大的地方就好了, 这个半径最大的位置一定在Fafa和公寓中心的连线上(前提是Fafa不和公寓中心重合且fafa在公寓范围内). 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4