zoukankan      html  css  js  c++  java
  • 序列合并

    Problem

    有一个序列,初始时为空,你会不断往序列末尾添加一个 ([1, m]) 的随机整数。

    任意时刻

    • 若序列末尾两个数相同(记为 (x)),且小于 (t),则这两个数会合并成 (x+1)

    • 若序列长度为 (n) 且无法合并,则操作结束。

    求序列中所有元素和的期望,答案对 (10^9+7) 取模。

    (1leq n,mleq 10^3)(mleq tleq 10^9)

    Solution

    (L=min{t, n+m-1})

    (p_{i,j}):限制序列长度为 (i),第一个位置出现 (j) 的概率。

    [p_{i,j}=[jleq m]frac1m+p_{i,j-1} imes p_{i-1,j-1} ]

    (q_{i,j}):限制序列长度为 (i),第一个位置为 (j) 下,之后不再改变的概率。

    [q_{i,j}=1-[j<L]p_{i-1,j} ]

    (g_{i,j}):限制序列长度为 (i),第一个位置为 (j),且之后不再改变后,整个序列的期望。

    (ans_i):序列长度为 (i) 时,权值和的期望。

    (f_{i,j}):序列长度为 (i),第一个数字出现 (j) 时,序列元素权值和。

    (j<L) 时,

    [egin{aligned} g_{i,j}&=j+sum_{S}S imesPr{第2到i权值和为S|第1个为j,且j不变}\ &=j+frac{sum_{S}S imesPr{第2到i权值和为S,j不改变|第1个为j}}{Pr{j不改变|第1个为j}}\ &=j+frac{sum_{S}S imesPr{第2到i权值和为S,j不改变|第1个为j}}{q_{i,j}}\ &=j+frac{sum_{S}S imesPr{第2到i权值和为S,j任意|第1个为j}-sum_{S}S imesPr{第2到i权值和为S,j改变|第1个为j}}{q_{i,j}}\ &=j+frac{ans_{i-1}-Pr{第2个为j} imessum_S S imesPr{第2到i权值和为S|第2个为j}}{q_{i,j}}\ &=j+frac{ans_{i-1}-p_{i-1,j} imes f_{i-1,j}}{q_{i,j}} end{aligned} ]

    (j=L) 时,

    [g_{i,j}=j+ans_{i-1} ]

    对于 (ans_i)

    [ans_i=sum_{j=1}^Lp_{i,j} imes q_{i,j} imes g_{i,j} ]

    对于 (f_{i,j})

    [f_{i,j}=q_{i,j} imes g_{i,j}+(1-q_{i,j}) imes f_{i,j+1} ]

    为了避免求逆元,将 (g_{i,j} imes q_{i,j}) 整体转移。复杂度 (mathcal O(nm))

    Code

    #include <bits/stdc++.h>
    const int N = 2005, P = 1e9 + 7;
    using std::min;
    int n, m, t, L, f[N][N], qg[N][N], p[N][N], q[N][N], ans[N];
    int qpow(int a, int b) {
    	int t = 1;
    	for (; b; b >>= 1, a = 1LL * a * a % P)
    		if (b & 1) t = 1LL * t * a % P;
    	return t;
    }
    int main() {
    	scanf("%d%d%d", &n, &m, &t); L = min(n + m - 1, t);
    	int inv = qpow(m, P-2);
    	for (int i = 1; i <= n; i++) {
    		for (int j = 1; j <= L; j++) {
    			p[i][j] = ((j <= m ? inv : 0) + 1LL * p[i][j - 1] * p[i - 1][j - 1]) % P;
    			q[i][j] = (1 - (j < L ? p[i - 1][j] : 0) + P) % P;
    		}
    		for (int j = L; j; j--) {
    			qg[i][j] = (1LL * q[i][j] * j + ans[i - 1] - (j < L ? 1LL * p[i - 1][j] * f[i - 1][j] % P : 0) + P) % P;
    			f[i][j] = (qg[i][j] + (j < L ? 1LL * (1 - q[i][j] + P) * f[i][j + 1] : 0)) % P;
    			ans[i] = (ans[i] + 1LL * p[i][j] * qg[i][j]) % P;
    		}
    	}
    	printf("%d
    ", ans[n]);
    	return 0;
    }
    
  • 相关阅读:
    理解OAuth 2.0
    asp.net core webapi/website+Azure DevOps+GitHub+Docker
    ASP.NET Core分布式项目实战
    Docker 在 centos 7上升级
    35.Docker安装Mysql挂载Host Volume
    34.Docker安装Mysql参数及环境变量使用
    33.Docker安装Mysql及用户配置
    32.Docker安装MongoDb
    如何用Spring Boot自定义Banner
    如何实现JDK10的新特性:var泛型和多个接口,案例详解
  • 原文地址:https://www.cnblogs.com/ac-evil/p/14433082.html
Copyright © 2011-2022 走看看