zoukankan      html  css  js  c++  java
  • 牛客小白月赛9 A签到(乘法逆元)

    你在一栋楼房下面,楼房一共有n层,第i层每秒有pi的概率会扔下一个东西并砸到你
    求第一秒内你被砸到的概率

    输入描述:

    第一行一个整数n
    之后有n行,第i+1行有两个整数a
    i
    ,b
    i
    ,表示

    输出描述:

    设答案为
    ,你只需要找到一个最小的非负整数T,使得

    输出这个T就行了
    示例1

    输入

    复制
    2
    1 2
    1 2

    输出

    复制
    750000006

    说明

    一共只有如下状态:

    1. 第一层和第二层都扔了下来

    2. 第一层扔了下来

    3. 第二层扔了下来

    4. 第一层和第二层都没有扔下来

    以上四种都是等概率发生的

    除了第四种情况外,都会被砸到

    因此被砸到的概率是 3/4,这个值在模1e9+7意义下就是750000006

    备注:

    数据范围
    0 ≤ n ≤ 10
    5

    1 ≤ a
    i
     ≤ b
    i
     ≤ 10
    5
     
    思路:题意很好懂,主要是求逆元
    对逆元不熟悉
     
    例如:4关于1模7的乘法逆元为多少?
    4X≡1 mod 7
    这个方程等价于求一个X和K,满足
    4X=7K+1
    其中X和K都是整数。
    若ax≡1 mod f, 则称a关于1模f的乘法逆元为x。也可表示为ax≡1(mod f)。
    当a与f互素时,a关于模f的乘法逆元有解。如果不互素,则无解。如果f为素数,则从1到f-1的任意数都与f互素,即在1到f-1之间都恰好有一个关于模f的乘法逆元。
    求此算法还可以使用费马小定理
    只不过局限性比较大,要求模数是素数
    a^(p-1)
    1(mod p)
    p要求是素数
    那么a^(p-2)就是a的乘法逆元
     
     
     
    首先是逆元的模板:
     1 // 扩展欧几里得做法;
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cstring>
     6 #define ll long long
     7 using namespace std;
     8 
     9 ll ex_gcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得(扩展gcd)
    10 {
    11     if (a==0&&b==0) return -1;
    12     if (b==0){x=1;y=0;return a;}
    13     ll d=ex_gcd(b,a%b,y,x);
    14     y-=a/b*x;
    15     return d;
    16 }
    17 
    18 ll mod_inverse(ll a,ll mod)//乘法逆元
    19 {
    20     ll x,y;
    21     ll d = ex_gcd(a,mod,x,y);
    22     return (x%mod+mod)%mod;
    23 }
    24 int low_bit(int x){return x&(-x);}
    25 int main()
    26 {
    27     for(int i=0;i<=16;i++)
    28         cout<<i<<' '<<low_bit(i)<<endl;
    29     return 0;
    30 }

    解题代码如下:

     1 #include<iostream>
     2 using namespace std;
     3 #define ll long long
     4 ll ex_gcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得(扩展gcd)
     5 {
     6     if (a==0&&b==0) return -1;
     7     if (b==0){x=1;y=0;return a;}
     8     ll d=ex_gcd(b,a%b,y,x);
     9     y-=a/b*x;
    10     return d;
    11 }
    12 
    13 ll mod_inverse(ll a,ll mod)//乘法逆元
    14 {
    15     ll x,y;
    16     ll d = ex_gcd(a,mod,x,y);
    17     return (x%mod+mod)%mod;
    18 }
    19 long long gcd(long long a,long long b)
    20 {
    21     long long c=1;
    22     while(c)
    23     {
    24         c=a%b;
    25         a=b;
    26         b=c;
    27     }
    28     return a;
    29 }
    30 int main()
    31 {
    32     int n;
    33     cin>>n;
    34     long long a,b,c,sum_a=1,sum_b=1;
    35     for(int i=0;i<n;i++)
    36     {
    37         cin>>a>>b;
    38         c=gcd(a,b);
    39         a/=c;
    40         b/=c;
    41         sum_a*=b-a;
    42         sum_b*=b;
    43         sum_b%=1000000007;
    44         sum_a%=1000000007;
    45     }
    46     c=gcd(sum_a,sum_b);
    47     sum_a/=c;
    48     sum_b/=c;
    49     sum_a=(sum_b-sum_a+1000000007)%10000000007;
    50     c=mod_inverse(sum_b,1000000007);
    51     cout<<c*sum_a%1000000007;
    52 }
  • 相关阅读:
    AC自动机讲解超详细
    区间树Splay——[NOI2005]维护数列
    区间树Splay——[NOI2005]维护数列
    Trie学习总结
    微信小程序刮刮乐
    微信小程序获得高度
    微信小程序多video播放暂停问题
    vue中的问题思考
    vue的开发技巧
    微信小程序消息推送,前端操作
  • 原文地址:https://www.cnblogs.com/lu1nacy/p/10013853.html
Copyright © 2011-2022 走看看