zoukankan      html  css  js  c++  java
  • [HNOI 2017]抛硬币

    Description

    题库链接

    两人抛硬币一人 (a) 次,一人 (b) 次。记正面朝上多的为胜。问抛出 (a) 次的人胜出的方案数。

    (1le a,ble 10^{15},ble ale b+10000,1le kle 9)

    Solution

    比较难,不会写,代码都是抄题解的...题解链接

    Code

    //It is made by Awson on 2018.3.6
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const LL INF = ~0u>>1;
    const LL mod5 = 1953125, mod2 = 512;
    
    LL a, b, k, mi2, mi5, yzh, K;
    LL f[6][mod5+1];
    
    void print(LL x, LL rest) {if (rest == 0) return; print(x/10, rest-1); putchar(x%10+'0'); }
    LL quick_pow(LL a, LL b, LL p) {
      LL ans = 1;
      while (b) {
        if (b&1) ans = ans*a%p;
        b >>= 1, a = a*a%p;
      }
      return ans;
    }
    void ex_gcd(LL a, LL b, LL &x, LL &y) {
      if (b == 0) {x = 1, y = 0; return; }
      ex_gcd(b, a%b, x, y);
      LL t = x; x = y; y = t-a/b*y;
    }
    LL inv(LL a, LL b) {
      LL x, y; ex_gcd(a, b, x, y);
      return (x%b+b)%b;
    }
    LL mul(LL n, LL pi, LL pk) {
      if (n == 0) return 1;
      LL ans = f[pi][pk]%pk;
      ans = quick_pow(ans, n/pk, pk);
      ans = ans*f[pi][n%pk]%pk;
      return ans*mul(n/pi, pi, pk)%pk;
    }
    LL C(LL n, LL m, LL pi, LL pk, bool flag) {
      LL k = 0;
      for (LL i = n; i; i = i/pi) k += i/pi;
      for (LL i = m; i; i = i/pi) k -= i/pi;
      for (LL i = n-m; i; i = i/pi) k-= i/pi;
      if (pi == 2 && !flag) --k; if (k >= K) return 0;
      LL a = mul(n, pi, pk), b = mul(m, pi, pk), c = mul(n-m, pi, pk);
      LL ans = a*inv(b, pk)%pk*inv(c, pk)%pk*quick_pow(pi, k, pk)%pk;
      if (pi == 5 && !flag) ans = ans*inv(2, pk)%pk;
      return ans;
    }
    LL ex_lucas(LL n, LL m, bool flag) {return (C(n, m, 2, mi2, flag)*mi5%yzh*inv(mi5, mi2)%yzh+C(n, m, 5, mi5, flag)*mi2%yzh*inv(mi2, mi5)%yzh+yzh)%yzh; }
    void work() {
      K = k; mi2 = quick_pow(2, k, INF), mi5 = quick_pow(5, k, INF), yzh = mi2*mi5;
      if (a == b) print((quick_pow(2, a*2-1, yzh)-ex_lucas(a*2, a, 0)+yzh)%yzh, k), puts("");
      else {
        LL ans = quick_pow(2, a+b-1, yzh);
        for (LL i = (a+b)/2+1; i < a; i++) ans = (ans+ex_lucas(a+b, i, 1))%yzh;
        if ((a+b)%2 == 0) ans = (ans+ex_lucas(a+b, (a+b)/2, 0))%yzh;
        print(ans, k), puts("");
      }
    }
    int main() {
      f[2][0] = f[5][0] = f[2][1] = f[5][1] = 1;
      for (LL i = 2; i <= mod2; i++) f[2][i] = (f[2][i-1])*(i%2 == 0 ? 1 : i)%mod2;
      for (LL i = 2; i <= mod5; i++) f[5][i] = (f[5][i-1])*(i%5 == 0 ? 1 : i)%mod5;
      while (~scanf("%lld%lld%lld", &a, &b, &k)) work(); return 0;
    }
  • 相关阅读:
    附加数据库 对于 服务器“00-PC”失败
    SQL 语句转换格式函数Cast、Convert
    sql语句:union
    ISNULL-sqlserver语句
    SQL中的CASE WHEN语句
    SQL SELECT INTO 语句
    Sql语句中IN等方面的用法
    combobox的不常用的方法和将txt文本内容加到textbox中显示
    程序员:“菜鸟”和“大神”差距在哪
    过劳死离我们有多远?
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8516667.html
Copyright © 2011-2022 走看看