zoukankan      html  css  js  c++  java
  • NOI Online #2 入门组 建设城市

    题目链接

    Solution

    首先枚举 x, y 的高度 i,分三种情况讨论:

    1. x, y 一个在左边,一个在右边:

    如图,两个方框分别代表 x, y,红线把数列分成 4 段,考虑对于每一段分别计算答案,然后相乘。对于每一段,其长度已经固定,取数范围也已经固定。例如,对于 l1,其长度为 x - 1,取数范围为 ([1,i])。组合数时使用可重复组合,计算公式为 (H_n^r = C_{n+r-1}^r)

    2. x, y 都在左边 仿照上例。

    3. x, y 都在右边 仿照上例。

    计算组合数时需要用到乘法逆元,可以预处理出阶乘的逆元。注意经常取模,稍微不注意就会爆 long long。

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define LL long long
    using namespace std;
    
    const int N = 6666666;
    const LL mod = 998244353;
    LL m, n, x, y, Ans = 0, inv[N], fac[N];
    
    LL poww(LL b, LL p)
    {
        LL res = 1;
        while(p)
        {
            if(p & 1) res = (res * b) % mod;
            b = (b * b) % mod;
            p >>= 1;
        }
        return res;
    }
    
    LL C(LL x, LL y) { return (fac[x] * ((inv[y] * inv[x - y]) % mod)) % mod; }
    
    int main()
    {
        scanf("%lld%lld%lld%lld", &m, &n, &x, &y);
        fac[0] = 1;
        for(int i = 1; i <= n * 2 + m; i++)
            fac[i] = (fac[i - 1] * i) % mod;
        inv[n * 2 + m] = poww(fac[n * 2 + m], mod - 2);
        inv[0] = 1;
        for(int i = n * 2 + m - 1; i > 0; i--)
            inv[i] = (inv[i + 1] * (i + 1) % mod + mod) % mod;
        if(x <= n && y >= n)
        {
            for(int i = 1; i <= m; i++)
            {
                LL l1 = x - 1, l2 = n * 2 - y, l3 = n - x, l4 = y - n - 1, now = 1;
                LL num1 = i, num2 = i, num3 = m - i + 1, num4 = m - i + 1;
                now = (now * C(num1 + l1 - 1, l1) + mod) % mod;
                now = (now * C(num2 + l2 - 1, l2) + mod) % mod;
                now = (now * C(num3 + l3 - 1, l3) + mod) % mod;
                now = (now * C(num4 + l4 - 1, l4) + mod) % mod;
                Ans = (Ans + now + mod) % mod;
            }
        }
        else if(y < n)
        {
            for(int i = 1; i <= m; i++)
            {
                LL l1 = x - 1, l2 = y - x - 1, l3 = n - y, l4 = n;
                LL num1 = i, num2 = 1, num3 = m - i + 1, num4 = m, now = 1;
                now = (now * C(num1 + l1 - 1, l1) + mod) % mod;
                now = (now * C(num2 + l2 - 1, l2) + mod) % mod;
                now = (now * C(num3 + l3 - 1, l3) + mod) % mod;
                now = (now * C(num4 + l4 - 1, l4) + mod) % mod;
                Ans = (Ans + now + mod) % mod;
            }
        }
        else
        {
            for(int i = 1; i <= m; i++)
            {
                LL l1 = n, l2 = x - n - 1, l3 = y - x - 1, l4 = n * 2 - y;
                LL num1 = m, num2 = m - i + 1, num3 = 1, num4 = i, now = 1;
                now = (now * C(num1 + l1 - 1, l1) + mod) % mod;
                now = (now * C(num2 + l2 - 1, l2) + mod) % mod;
                now = (now * C(num3 + l3 - 1, l3) + mod) % mod;
                now = (now * C(num4 + l4 - 1, l4) + mod) % mod;
                Ans = (Ans + now + mod) % mod;
            }
        }
        printf("%lld", Ans);
        return 0;
    }
    
  • 相关阅读:
    HttpRequestHandler处理页面
    netty常用handler
    基于Netty实现高性能弹幕系统
    netty异步任务
    九、Netty源码剖析
    八、Netty实现简单RPC调用
    6、SSM整合Shiro
    5、Shiro实现授权
    4、散列算法&凭证配置
    3、Shiro实现认证
  • 原文地址:https://www.cnblogs.com/Andy-park/p/13580906.html
Copyright © 2011-2022 走看看