• 【LOJ6374】[SDWC2018 Day1]网格


    【LOJ6374】[SDWC2018 Day1]网格

    题面

    loj

    题解

    先考虑一下没有限制而且可以同时不走的,那么显然行列是独立的。
    ( ext{f}(R,T,M))表示某一维走出步数(R),走(T)格,每步不超过(M),令生成函数( ext{F}(x)=1+x+x^2+cdots +x^M=frac {1-x^{M+1}}{1-x}),那么我们想求的就是([x^T] ext{F}(x)^R)
    其中
    ( egin{aligned} ext{[}x^T ext{]} ext{F}(x)^R &=[x^T](frac {1-x^{M+1}}{1-x})^R\ &=[x^T](1-x^{M+1})^R(1+x+x^2+cdots)^R\ &=[x^T](1-x^{M+1})^Rsum_{i=0}^{infty}{i+R-1choose R-1}x^i\ &=sum_{i=0}^{lfloorfrac {T}{M+1} floor}(-1)^i{Rchoose i}{R-1+T-i(M+1)choose R-1} end{aligned} )

    然后再考虑可以有((0,0))限制的:
    可以发现( ext f(R,T_x,M_x) imes ext f(R,T_y,M_y))没有考虑((0,0)),那也就是至多走了(R)步的方案数,而非恰好
    ( ext g(R,T_x,T_y,M_x,M_y))表示恰好(R)步,然后里面参数自己看的答案,二项式反演得:
    ( ext g(R,T_x,T_y,M_x,M_y)=sum_{i=0}^R (-1)^{R-i}{Rchoose i} ext f(i,T_x,M_x) imes ext f(i,T_y,M_y))

    现在再考虑有那(K)条限制的:
    可以背包出( ext h(i,j))表示从(K)中选了(i)步走,走了(j imes G)格的方案数,那么放到总步数(R)中,方案数就有({R choose i} ext h(i,j))种。

    最后就可以求出答案了:
    考虑容斥,首先枚举至少踩了(i)条限制,再枚举限制走了(j imes G)步,那么答案为(不妨令(T_x<T_y))

    [Ans=sum_{i=0}^R(-1)^i{R choose i}sum_{j=0}^{lfloorfrac {T_x}G floor} ext h(i,j) ext g(R-i,T_x-j imes G,T_y-j imes G,M_x,M_y) ]

    计算的复杂度为(O(R^2lfloor frac TG floor)),可以通过。

    代码

    #include <bits/stdc++.h> 
    using namespace std; 
    int gi() { 
    	int res = 0, w = 1; 
    	char ch = getchar(); 
    	while (ch != '-' && !isdigit(ch)) ch = getchar(); 
    	if (ch == '-') w = -1, ch = getchar(); 
    	while (isdigit(ch)) res = res * 10 + ch - '0', ch = getchar(); 
    	return res * w; 
    }
    const int Mod = 1e9 + 7; 
    int fpow(int x, int y) {
    	int res = 1; 
    	while (y) {
    		if (y & 1) res = 1ll * res * x % Mod; 
    		x = 1ll * x * x % Mod; 
    		y >>= 1; 
    	} 
    	return res; 
    } 
    const int MAX_N = 1.2e6 + 5; 
    int N = 1.2e6, Tx, Ty, Mx, My; 
    int R, G, K, a[55]; 
    int fac[MAX_N], ifc[MAX_N]; 
    int C(int n, int m) { 
    	if (n < m || n < 0 || m < 0) return 0; 
    	else return 1ll * fac[n] * ifc[m] % Mod * ifc[n - m] % Mod; 
    } 
    int f(int R, int T, int M) { 
    	int n = T / (M + 1), res = 0; 
    	for (int i = 0; i <= n; i++) { 
    		int now = 1ll * C(R - 1 + T - i * (M + 1), R - 1) * C(R, i) % Mod; 
    		if (i & 1) res = (res - now + Mod) % Mod; 
    		else res = (res + now) % Mod; 
    	} 
    	return res; 
    } 
    int g(int R, int Tx, int Ty, int Mx, int My) { 
    	int res = 0; 
    	for (int i = 0; i <= R; i++) { 
    		int now = 1ll * C(R, i) * f(i, Tx, Mx) % Mod * f(i, Ty, My) % Mod; 
    		if ((R - i) & 1) res = (res - now + Mod) % Mod; 
    		else res = (res + now) % Mod; 
    	} 
    	return res; 
    } 
    int h[1005][1005]; 
    int main () { 
    #ifndef ONLINE_JUDGE 
        freopen("cpp.in", "r", stdin);
    #endif 
    	for (int i = fac[0] = 1; i <= N; i++) fac[i] = 1ll * fac[i - 1] * i % Mod; 
    	ifc[N] = fpow(fac[N], Mod - 2); 
    	for (int i = N - 1; ~i; i--) ifc[i] = 1ll * ifc[i + 1] * (i + 1) % Mod; 
    	Tx = gi(), Ty = gi(), Mx = gi(), My = gi(); 
    	R = gi(), G = gi(), K = gi(); 
    	for (int i = 1; i <= K; i++) a[i] = gi() / G; 
    	sort(&a[1], &a[K + 1]); K = unique(&a[1], &a[K + 1]) - a - 1; 
    	h[0][0] = 1; 
    	int mx = max(Tx, Ty) / G; 
    	for (int i = 1; i <= min(mx, R); i++) 
    		for (int j = 1; j <= K; j++) 
    			for (int k = a[j]; k <= mx; k++) h[i][k] = (h[i][k] + h[i - 1][k - a[j]]) % Mod;
    	int ans = 0; 
    	for (int i = 0; i <= R; i++) { 
    		int res = 0; 
    		for (int j = 0; j <= mx; j++) 
    			res = (res + 1ll * h[i][j] * g(R - i, Tx - j * G, Ty - j * G, Mx, My)) % Mod; 
    		res = 1ll * res * C(R, i) % Mod; 
    		if (i & 1) ans = (ans - res + Mod) % Mod; 
    		else ans = (ans + res) % Mod; 
    	} 
    	printf("%d
    ", ans); 
        return 0; 
    } 
    
  • 相关阅读:
    统计:概述
    概率论总结
    概率论13 中心极限定律
    概率论12 矩与矩生成函数
    概率论11 协方差与相关系数
    概率论10 方差与标准差
    概率论09 期望
    概率论08 随机变量的函数
    mysql 分区
    Linux 搭建svn版本库
  • 原文地址:https://www.cnblogs.com/heyujun/p/13568339.html
Copyright © 2020-2023  润新知