zoukankan      html  css  js  c++  java
  • 【XSY2472】string

    题目

    Description
    输入文件: string.in
    输出文件: string.out

    给定一个由且仅由字符 'H' , 'T' 构成的字符串 (S) .
    给定一个最初为空的字符串 (T) , 每次随机地在 T 的末尾添加 'H' 或者 'T' .
    问当 (S)(T) 的后缀时, 在末尾添加字符的期望次数.

    Input
    输入只有一行, 一个字符串 (S) .

    Output
    输出只有一行, 一个数表示答案.
    为了防止运算越界, 你只用将答案对 (10^9+7) 取模.

    题解

    题目可以理解成不断向(T)添加字符, 直到(S)匹配上(T)(()(S)为模式串()), 的期望长度。
    于是我们可以预处理出失配指针(f_i)

    我们可以设(dp_i)表示现在已匹配到(S_i), 在匹配上(S_{i+1})的期望次数。
    于是我们可以分类讨论一下。
    如果这一次直接匹配上(S_{i+1}), 那么这一部分的贡献为(frac{1}{2} imes 1 = frac{1}{2})
    如果这一次匹配失败跳了失配指针, 贡献为匹配上(S_{f_i,;i+1})的期望次数(()参考KMP匹配过程()), 也就是(frac{1}{2}(sum_{k = f_i}^i dp_k) + frac{1}{2})(()(frac{1}{2})是因为要匹配上(S_{i+1})())
    于是(dp_i = frac{1}{2} + frac{1}{2} + frac{1}{2}(sum_{k = f_i}^i dp_k))
    注意到等号两边都出现了(dp_i), 于是我们可以把上面的式子当成一个方程, 解出来是(dp_i = 2 + sum_{k = f_i}^{i-1} dp_k), 我们用前缀和优化一下, 单次转移就变成(O(1))了。

    代码

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    
    const int mod = 1e9 + 7;
    
    
    const int N = 1000010;
    
    
    char S[N];
    
    int f[N], nxt[N][2];
    
    
    int sum[N], dp[N];
    
    
    int main()
    {
    	scanf("%s", S + 1);
    	
    	int n = strlen(S + 1);
    	
    	f[1] = 0;
    	int j = 0;
    	for (int i = 2; i <= n; i++)
    	{
    		while (j && S[i] != S[j+1]) j = f[j];
    		if (S[i] == S[j+1]) j++;
    		f[i] = j;
    	}
    	
    	for (int i = 0; i < n; i++)
    		if (S[i+1] == 'H')
    			nxt[i][0] = i + 1, nxt[i][1] = nxt[f[i]][1];
    		else
    			nxt[i][0] = nxt[f[i]][0], nxt[i][1] = i + 1;
    	
    	sum[0] = f[0] = 2;
    	for (int i = 1; i < n; i++)
    	{
    		int g;
    		if (S[i+1] == 'H') g = nxt[i][1];  else g = nxt[i][0];
    		dp[i] = ((sum[i-1] - (g ? sum[g-1] : 0) + 2) % mod + mod) % mod;
    		sum[i] = (sum[i-1] + dp[i]) % mod;
    	}
    	
    	printf("%d
    ", (sum[n-1] + mod) % mod);
    	
    	return 0;
    }
    
  • 相关阅读:
    NanUI for Winform发布,让Winform界面设计拥有无限可能
    新浪微博.Net SDK第三版源代码和示例【最后一次更新了】
    写个C#命令行参数解析的小工具
    Mac安装Windows 10的简明教程
    自己动手,让Entity Framework Power Tools在VS2015重放光彩
    C++CLI使用.net委托,*Callback注意"this"
    【转】IIS上的反向代理
    asp.net mvc 验证码
    win2008R2 下解决关于mysql odbc无法正常工作问题
    中国健康医学教育网
  • 原文地址:https://www.cnblogs.com/2016gdgzoi509/p/11347978.html
Copyright © 2011-2022 走看看