zoukankan      html  css  js  c++  java
  • 「6月雅礼集训 2017 Day2」B

    【题目大意】

    求n*n的棋盘,每行每列都有2个黑格子的方案数。

    n<=10^7

    【题解】

    zzq的做法好神奇啊

    行列建点,二分图

    左边有i个点,右边有j个点的方案数 f[i,j]

    左边有i个点,2个已经有1个度,右边有j个点的方案数 g[i,j]

    g[i,j] = f[i-2,j-1]*j + g[j,i-2]*P(j,2)

    f[i,j] = g[i,j-1] * C(i,2) = g[j,i-1] * C(j,2)

    g[j,i-2] = g[i-1,j-1] * C(i-1,2) / C(j,2)

    g[i,j] = g[i-2,j-2] * C(i-2,2) * j + g[i-1, j-1] * C(i-1,2) / C(j,2) * P(j,2)

    g[i,j] = g[i-2,j-2] * C(i-2,2) * j + g[i-1, j-1] * C(i-1,2) * 2

    g[x] = g[x, x-1] 

    g[x] = g[x-2] * C(x-2, 2) * (x-1) + g[x-1] * C(x-1, 2) * 2

    ans = sigma (C(x,2) * g[x])

    Q: 为什么从f转移到g,只乘了右边选择的部分,不管左边;从g转移到f,只乘了左边的部分,不管右边?

    A: g实际的意义是我钦定左边最后两个度数为1的方案数,f实际的意义是我钦定右边最后1或2个是我最后填进来。 我从g到f,目的是消去两个度为1的点,重点是消去,我要优先考虑消除哪两个点,按照我g的定义,每两个度数为1的点作为选择,都有这么多方案,所以要乘组合数;从f到g,目的是制造两个度为1的点,按照f的定义,每1或2个点作为选择,都有这么多方案,所以要乘j和后面的那个组合数。意义在于,我要有一个顺序来填数,不能xjb填,这样会统计重复方案,我们用钦(ying)点来避免这样的问题。

     

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    
    # define RG register
    # define ST static
    
    const int M = 1e7 + 10;
    const int mod = 998244353;
    
    int n, g[M], ans;
    
    inline int C(int n, int k = 2) {
        return (ll)n * (n-1) / 2 % mod;
    }
    
    int main() {
    //    freopen("B.in", "r", stdin);
    //    freopen("B.out", "w", stdout);
        cin >> n;
        g[1] = 0, g[2] = 1;
        for (int i=3; i<=n; ++i) {
            g[i] = 1ll * C(i-2) * (i-1) % mod * g[i-2] % mod + 2ll * C(i-1) * g[i-1] % mod; 
            if(g[i] >= mod) g[i] -= mod;
        }
        for (int i=1; i<=n; ++i) {
            ans += 1ll * C(i) * g[i] % mod;
            if(ans >= mod) ans -= mod;
        }
        cout << ans; 
        return 0;
    }
    View Code

    多贴几份考试写的各种暴力吧qwq

    O(n^2)求单点暴力

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    
    # define RG register
    # define ST static
    
    const int M = 1e4 + 10, N = 1e5 + 10;
    const int mod = 998244353;
    
    int n, f[2][M];
    // row i, line2: j line1: k line0: l
    
    inline int C(int n, int k) {
        if(k == 1) return n;
        if(k == 2) return (ll)n * (n-1) / 2 % mod;
    }
    
    int main() {
    //    freopen("B.in", "r", stdin);
    //    freopen("B.out", "w", stdout);
        int pre = 0, cur = 1; cin >> n;
        for (int j=0; j<=n; ++j) f[pre][j] = 0;
        f[pre][0] = 1;
        for (int i=1; i<=n; ++i) {
            for (int j=0; j<=i; ++j) {
                f[cur][j] = 0;
                // i*2 = j*2 + k => k = i*2 - j*2
                int k = i*2 - j*2, l = n-j-k;
    //            printf("%d line2: %d   line1: %d   line0: %d
    ", i, j, k, l);
                if(l < 0) continue;
                if(j >= 2) {
                    f[cur][j] += 1ll * C(k+2, 2) * f[pre][j-2] % mod;
                    if(f[cur][j] >= mod) f[cur][j] -= mod;
                }
                if(k >= 2) {
                    f[cur][j] += 1ll * C(l+2, 2) * f[pre][j] % mod;
                    if(f[cur][j] >= mod) f[cur][j] -= mod;
                }
                if(j && k) {
                    f[cur][j] += 1ll * C(k, 1) * C(l+1, 1) * f[pre][j-1] % mod;     // 10w: need mod again
                    if(f[cur][j] >= mod) f[cur][j] -= mod;
                }
    //            printf("F = %d
    ", f[i][j]); 
            }
            swap(pre, cur);
        }
        cout << f[pre][n] << ',';
    
        return 0;
    }
    View Code

    把含有n-...的项换成不含n的等价表示就有70分了。。

    我是考试的时候打了个1w的表发现100K,压了一半,套这个做法。。50(被评测机卡)

  • 相关阅读:
    Linux命令之more
    Linux命令之sort
    STM32启动模式
    poll调用深入解析
    STM32 控制步进电机 28BYJ-48
    NEC协议
    家用宽带的上传和下载速度
    Ubuntu14.04更新源
    波特率和比特率【串口为例】
    CentOS: make menuconfig error: curses.h: No such file or directory
  • 原文地址:https://www.cnblogs.com/galaxies/p/20170618_b.html
Copyright © 2011-2022 走看看