zoukankan      html  css  js  c++  java
  • 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 temples. Fafa and Fifa went to one of the temples and found two non-empty words S1 and S2 of equal lengths on the wall of temple written one below the other. Since this temple is very ancient, some symbols from the words were erased. The symbols in the set  have equal probability for being in the position of any erased symbol.

    Fifa challenged Fafa to calculate the probability that S1 is lexicographically greater than S2. Can you help Fafa with this task?

    You know that , i. e. there were m distinct characters in Egyptians' alphabet, in this problem these characters are denoted by integers from 1 to m in alphabet order. A word x is lexicographically greater than a word y of the same length, if the words are same up to some position, and then the word x has a larger character, than the word y.

    We can prove that the probability equals to some fraction , where P and Q are coprime integers, and . Print as the answer the value , i. e. such a non-negative integer less than 109 + 7, such that , where  means that a and b give the same remainders when divided by m.

    Input

    The first line contains two integers n and m (1 ≤ n,  m ≤ 105) — the length of each of the two words and the size of the alphabet , respectively.

    The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ m) — the symbols of S1. If ai = 0, then the symbol at position i was erased.

    The third line contains n integers representing S2 with the same format as S1.

    Output

    Print the value , where P and Q are coprime and  is the answer to the problem.

    Examples
    input
    Copy
    1 2
    0
    1
    output
    Copy
    500000004
    input
    Copy
    1 2
    1
    0
    output
    Copy
    0
    input
    Copy
    7 26
    0 15 12 9 13 0 14
    11 1 0 13 15 12 0
    output
    Copy
    230769233
    Note

    In the first sample, the first word can be converted into (1) or (2). The second option is the only one that will make it lexicographically larger than the second word. So, the answer to the problem will be , that is 500000004, because .

    In the second example, there is no replacement for the zero in the second word that will make the first one lexicographically larger. So, the answer to the problem is , that is 0.

    题意:给两个长度为n的数列,每个数列的数字范围是1-m,有可能出现缺失的部分(用0表示),在缺失的部分每个数字出现的概率相同(都是1/m),问最后a的字典序比b的大的概率.输入是 n,m 之后两行每行n个数,分别代表序列a,b.最后输出概率对1e9+7取模

    提示:分数无法取模,所以要用逆元~另外要注意一下取模不然会爆

    貌似有更简单的转移方式,只用一维就可以,也可以滚动数组写,但是我太弱了qwq

    分几种情况讨论然后直接转移就行啦,这道题其实就是一个递推

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 100010
     5 #define mod 1000000007 
     6 #define ll long long
     7 using namespace std;
     8 int n,m;
     9 int a[maxn],b[maxn];
    10 ll inv[maxn],f[maxn][2];//f[i][1]表示到i位为止,a>b的概率
    11 ll fp(ll x,ll a){//在jms学到的神奇写法
    12     ll ret=1;
    13     for(x%=mod;a;a>>=1,x=x*x%mod)
    14         if(a&1) ret=ret*x%mod;
    15     return ret; 
    16 }
    17 int main(){
    18     scanf("%d%d",&n,&m);//长度为n 字母表中有m个字母
    19     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    20     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    21     f[0][0]=1;
    22     ll invm=fp(m,mod-2),inv2=fp(2,mod-2);
    23     for(int i=1;i<=n;i++){
    24         if(a[i]>b[i]&&b[i]) //这一位都已经确定,直接转移即可
    25             f[i][1]=(f[i-1][1]+f[i-1][0])%mod;
    26         else if(a[i]<b[i]&&a[i]) 
    27             f[i][1]=f[i-1][1];//f[i][0]=0
    28         else if(a[i]==b[i]&&a[i])
    29             f[i][1]=f[i-1][1],f[i][0]=f[i-1][0]%mod;
    30         else if(!a[i]&&!b[i]){
    31             f[i][0]=f[i-1][0]*invm%mod;
    32             f[i][1]=(f[i-1][1]+((f[i-1][0]*((1-invm)%mod+mod)%mod)%mod*inv2)%mod)%mod;//相等的概率是1/m,剩下的对半分
    33         }
    34         else if(!a[i]){
    35             f[i][0]=f[i-1][0]*invm%mod;
    36             f[i][1]=(f[i-1][1]+(f[i-1][0]*(invm*((m-b[i])%mod+mod)%mod)%mod)%mod)%mod;
    37         }
    38         else if(!b[i]){
    39             f[i][0]=f[i-1][0]*invm%mod;
    40             f[i][1]=(f[i-1][1]+(f[i-1][0]*(invm*((a[i]-1)%mod+mod)%mod)%mod)%mod+mod)%mod;
    41         }
    42     }
    43     printf("%lld
    ",(f[n][1]%mod+mod)%mod);
    44     return 0;
    45 }
  • 相关阅读:
    学习Spring,看这几本书就够了
    这份书单会告诉你,Java网络编程其实很重要
    心雨(三)【英语】
    成功安装SQL Server实例后 无法找到SQL Server Configuration Manager工具的解决方案
    Windows Cluster失败后,AlwaysOn在残存Server节点上快速恢复DB的详细步骤
    SQL Server 数据库本地备份文件通过OSS工具上阿里云(恢复还原数据库)
    透过systemctl管理mysqld服务
    MongoDB 读偏好设置中增加最大有效延迟时间的参数
    MongoDB 副本集丢失数据的测试
    MySQL 时间类型 DATE、DATETIME和TIMESTAMP
  • 原文地址:https://www.cnblogs.com/al76/p/9583478.html
Copyright © 2011-2022 走看看