• 【Codechef】BB-Billboards


    题解

    传说中的……半标准杨表(行单调不增,列单调减)

    如果N能整除M,我们把序列分成(frac{N}{M})

    然后里面要填K个1,显然我每一段必须填K个1,且可以构造出合法的序列,所以最少要填(Kfrac{N}{M})个1

    我们列出一个K行(frac{N}{M})列的矩阵,((i,j))表示第j段第i个1填的位置,显然列是单调降的,而每行需要单调不增

    这是一个半标准的杨表

    公式是(prod_{(i,j)} frac{r + j - i}{hook(i,j)})

    r是值域的大小

    然后我们把要乘的数和要除的数列成一个矩阵,就会发现我们会约掉很多,只剩下两边总的大小不超过(M*K)的矩阵

    那么(N)不整除(M)呢,我们根据(N % M)分类一下,设(P = N % M)(P < M - K),那么我们前面(P)位必须都填0
    如果(P > M - K),那么我们新增一段,每段后(M - P)个位置必须填1
    如果(P = M - K),那么只有唯一的一种方案

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define pdi pair<db,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define eps 1e-8
    #define mo 974711
    #define MAXN 2005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    int N,M,K;
    const int MOD = 1000000007;
    int inv[205];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    void Solve(int r,int c,int m) {
        int hr = r + c - 1,hl = r;
        int tl = m,tr = m + c - 1;
        int res = 1;
        for(int i = hl ; i < tl ; ++i) {
    	for(int k = 0 ; k < r ; ++k) {
    	    res = mul(res,inv[i - k]); 
    	}
        }
        for(int i = hr + 1 ; i <= tr ; ++i) {
    	for(int k = 0 ; k < r ; ++k) {
    	    res = mul(res,i - k);
    	}
        }
        out(res);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        int T;
        read(T);
        inv[1] = 1;
        for(int i = 2 ; i <= 200 ; ++i) {
    	inv[i] = mul(inv[MOD % i],MOD - MOD / i); 
        }
    
        while(T--) {
    	read(N);read(M);read(K);
    	int P = N % M;
    	if(P == M - K) puts("1");
    	else if(P < M - K) Solve(K,N / M,M - P);
    	else Solve(K - (M - P),N / M + 1,P);
        }
        return 0;
    }
    
  • 相关阅读:
    TreeList Linq
    MasterDetail Linq
    C# 事务处理
    设计模式——代理模式(Proxy Pattern)
    设计模式——装饰模式(Decorator Pattern)
    C# 调用WCF服务
    加密解密
    Effective C#高效编程(02:常量)
    切换城市功能
    DataPager控件使用
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10113546.html
Copyright © 2020-2023  润新知