• CF708E Student's Camp


    CF708E Student's Camp

    看题解人 所以本地写了一遍然后放在cnblog上选了“只有我”的权限在cnblog修好后会不会显示。。。

    网格始终保持联通,等价于要求 \(k\) 天后,任意相邻两行剩下的区间有交。

    \(f_{i,l,r}\) 表示 \(1\)\(i\) 行符合要求且第 \(i\) 行剩下的砖是 \([l,r]\) 的概率。

    考虑风对于指定的某一行的某一边吹掉 \(i\) 块砖的概率:

    \[D(i)={k\choose i }p^i(1-p)^{k-i} \]

    考虑特定的一行剩下 \([l,r]\) 的概率:

    \[P(l,r)=D(l-1)D(m-r) \]

    考虑计算 \(f_{i,l,r}\)

    \[f_{i,l,r}=P(l,r)\sum_{[l',r']∩[l,r]\neq ∅}f_{i-1,l',r'}\\ f_{i,l,r}=D(l-1)D(m-r)(\sum_{l'\le r'} f_{i-1,l',r'}-\sum_{r'<l} f_{i-1,l',r'}-\sum_{l'>r} f_{i-1,l',r'}) \]

    复杂度 \(O(nm^2)\) 需要优化。

    \[F(i)=\sum_{l\le r} f_{i,l,r}\\ L(i,x)=\sum_{l\le r<x} f_{i,l,r}=\sum_{r=1}^{x-1} \sum_{l=1}^r f_{i,l,r}\\ R(i,x)=\sum_{r\ge l>x} f_{i,l,r}=\sum_{l=x+1}^m \sum_{r=l}^m f_{i,l,r}\\ f_{i,l,r}=D(l-1)D(m-r)(F(i-1)-L(i-1,l)-R(i-1,t))\\ \]

    显然 \(L\)\(R\) 非常对称。 \(L(i,x)=R(i,m+1-x)\) 因此这里只考虑 \(L\) 的求解。

    \(S_L(i,r)\) 为右端点为 \(r\)\(f_{i,l,r}\) 之和。

    \[L(i,x)=\sum_{r=1}^{x-1} S_L(i,r) \\F(i)=\sum_{r=1}^m S_L(i,r) \]

    \[\begin{aligned} S_L(i,r)&=\sum_{l\le r} f_{i,l,r}\\ &=\sum_{l\le r} D(l-1)D(m-r)(F(i-1)-L(i-1,l)-R(i-1,r))\\ &=D(m-r)\sum_{l\le r} D(l-1)(F(i-1)-L(i-1,l)-R(i-1,r))\\ &=D(m-r)( \ (F(i-1)-R(i-1,r))\sum_{l\le r} D(l-1)-\sum_{l\le r} (D(l-1)L(i-1,l))\ ) \end{aligned} \]

    因此对 \(D(l-1)\)\(D(l-1)L(i-1,l)\) 做前缀和 ,计算出 \(S_L(i,r)\) ,计算出 \(L(i,l)\),以此类推,直到算出最终答案。

    时间复杂度 \(O(nm)\) ,空间复杂度通过滚动可以优化为 \(O(m)\) (可以,但没必要)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1510,K=100010,mod=1e9+7;
    int n,m,a,b,k;
    int tmpp[K],tmp1p[K],C[K],d[K],sum[K];
    int sumdl[N],tmpsum[N],s[N][N],F[N],L[N][N];
    int power(int x,int y){
    	int ret=1;
    	while(y){
    		if(y&1) ret=1ll*ret*x%mod;
    		x=1ll*x*x%mod; y>>=1;
    	}
    	return ret;
    }
    int main(){
    //	freopen("ex.in","r",stdin);
    	//freopen("ex.out","w",stdout);
    	scanf("%d%d%d%d%d",&n,&m,&a,&b,&k);
    	int p=1ll*a*power(b,mod-2)%mod;
    	tmpp[0]=tmp1p[0]=C[0]=1;
    	for(int i=1;i<=k;i++){
    		tmpp[i]=1ll*tmpp[i-1]*p%mod;
    		tmp1p[i]=1ll*tmp1p[i-1]*((1+mod-p)%mod)%mod;
    	}
    	for(int i=0;i<=min(m,k);i++){
    		if(i) C[i]=1ll*(k-i+1)*power(i,mod-2)%mod*C[i-1]%mod;
    		d[i]=1ll*C[i]*tmpp[i]%mod*tmp1p[k-i]%mod;
    	}
    	for(int i=0;i<=m;i++) sum[i]=(i)?((sum[i-1]+d[i])%mod):d[i];
    	s[0][m]=1; F[0]=1; 
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			int tmp=(1ll*((F[i-1]+mod-L[i-1][m+1-j])%mod)*sum[j-1]%mod+mod-sumdl[j])%mod;
    			s[i][j]=1ll*d[m-j]*tmp%mod;
    			tmpsum[j]=(tmpsum[j-1]+s[i][j])%mod;
    			//求s
    		}
    		for(int j=1;j<=m;j++){
    			L[i][j]=tmpsum[j-1];
    			sumdl[j]=(sumdl[j-1]+1ll*d[j-1]*L[i][j]%mod)%mod;
    		}
    		F[i]=tmpsum[m];
    	}
    	printf("%d\n",F[n]);
    	return 0;
    }
    
  • 相关阅读:
    Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
    Windows Server 2016 辅助域控制器搭建
    Windows Server 2016 主域控制器搭建
    Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法
    SQL SERVER 2012更改默认的端口号为1772
    Windows下彻底卸载删除SQL Serever2012
    在Windows Server2016中安装SQL Server2016
    SQL Server 创建索引
    C#控制台或应用程序中两个多个Main()方法的设置
    Icon cache rebuilding with Delphi(Delphi 清除Windows 图标缓存源代码)
  • 原文地址:https://www.cnblogs.com/zdsrs060330/p/14570685.html
Copyright © 2020-2023  润新知