• bzoj3622 已经没有什么好害怕的了


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3622

    【题解】

    XJOI noip模拟题的一题吧

    这题统计方法用容斥

    f[i,j]表示前i个人,j个一定赢,其他不管的方案数。

    先考虑一定赢的转移,最后乘不论输赢的排列即可。

    那么ans[n] = f[n,n]

    ans[i] = f[n,i] - sigma(ans[j] * C(j,i)),其中j>i

    j个人赢了,挑任意i个人出来都符合条件,减去

    最后答案为ans[nWin]。

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 2e3 + 10;
    const int mod = 1e9+9;
    
    # define RG register
    # define ST static
    
    int n, K, a[M], b[M];
    int f[M][M], C[M][M], fac[M], ok[M], ans[M];
    
    int main() {
        cin >> n >> K;
        if((n+K)&1) {
            puts("0");
            return 0;
        }
        fac[0] = 1; 
        for (int i=1; i<=n; ++i) fac[i] = 1ll * fac[i-1] * i % mod; 
        C[0][0] = 1;
        for (int i=1; i<=n; ++i) {
            C[i][0] = 1; 
            for (int j=1; j<=i; ++j) { 
                C[i][j] = C[i-1][j] + C[i-1][j-1]; 
                if(C[i][j] >= mod) C[i][j] -= mod;
            }
        }
        for (int i=1; i<=n; ++i) scanf("%d", a+i);
        for (int i=1; i<=n; ++i) scanf("%d", b+i);
        int nWin = (n+K)/2, nLose = (n-K)/2;
        sort(a+1, a+n+1); 
        sort(b+1, b+n+1);
        for (int i=1; i<=n; ++i) ok[i] = upper_bound(b+1, b+n+1, a[i]) - b - 1; 
        f[0][0] = 1; 
        for (int i=1; i<=n; ++i) { 
            for (int j=0; j<=i; ++j) {
                f[i][j] = f[i-1][j];
                if(j && ok[i]-(j-1) > 0) {
                    f[i][j] += 1ll * f[i-1][j-1] * (ok[i] - (j-1)) % mod;
                    if(f[i][j] >= mod) f[i][j] -= mod;
                }
            }
        }
        int *F = f[n]; 
        for (int i=0; i<=n; ++i) F[i] = 1ll * F[i] * fac[n-i] % mod;
        for (int i=n; i>=0; --i) {
            ans[i] = F[i]; 
            for (int j=i+1; j<=n; ++j) {
                ans[i] -= 1ll * ans[j] * C[j][i] % mod;
                if(ans[i] < 0) ans[i] += mod;
            }
        }
        cout << ans[nWin] << endl; 
        return 0;
    }
    View Code
  • 相关阅读:
    (转)如何搭建一个vue项目
    vue项目设置自动打开浏览器
    vue项目关闭代码校验
    前端面试知识点
    图片瀑布流,so easy!
    详细梳理ajax跨域4种解决方案
    css实现内容不相同的左右两个div等高
    简单了解css3轮廓outline
    vue事件监听机制
    table-layout:fixed
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj3622.html
Copyright © 2020-2023  润新知