• Jzoj2934 字符串函数


    两个等长的由大写英文字母构成的字符串a和b,从a中选择连续子串x,从b中选出连续子串y。

    定义函数f(x,y)为满足条件xi=yi(1<=i<=|x|)的i的个数,计算f(x,y)的数学期望。(|x|=|y|)  


    首先显然不能每个串暴力,我们考虑单独计算每一个字符的贡献

    对于b[i],若我们找到a[j]=b[i],可以分两种情况讨论

    1.i<j 那么显然,对于b的字串,开头为[1,i],可以在a中找到完全对应的[j-i+1,j],而对于a的结尾则必然为[j,n],在b中可以找到[i,i+n-j]

    所以贡献就是i*j

    2.i>j 情况是对称的,所以贡献是(n-i+1)*(n-j+1)


    所以对于a,我们维护一个前缀和sf[i][c]表示所有j满足j<=i而且a[j]=c的j的和,和一个后缀和sb[i][c]表示所有j满足j>=i且a[j]=c的就的和

    那么对于b[i],贡献就是(n-i+1)*sf[i][b[i]]+i*sb[i+1][b[i]],累加即可,最后除以总方案数

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    char a[200010],b[200010]; double A=0;
    int n,sf[200010][26],sb[200010][26];
    int main(){
    	scanf("%d%s%s",&n,a+1,b+1);
    	for(int i=1;i<=n;++i){
    		memcpy(sf[i],sf[i-1],26<<2);
    		sf[i][a[i]-'A']=sf[i-1][a[i]-'A']+i;
    	}
    	for(int i=n;i;--i){
    		memcpy(sb[i],sb[i+1],26<<2);
    		sb[i][a[i]-'A']=sb[i+1][a[i]-'A']+(n-i+1);
    	}
    	for(long long i=1;i<=n;++i)
    		A+=(n-i+1)*(sf[i][b[i]-'A'])+i*(sb[i+1][b[i]-'A']); //这里+1是为了防止重复计算
    	printf("%.6lf
    ",A*6/((n+1ll)*(n*2ll+1)*n));
    }


  • 相关阅读:
    python学习之路---day16--面向对象
    python-day15---面向对象
    python---day14( 内置函数二)
    day13--------python 内置函数(一)
    python学习之路---day12
    python学习之路---day09
    python学习之路---day07
    【转帖】嵌入式4412开发板QT5.7编译安装到arm
    【转载】4412开发板嵌入式QtE应用开发环境搭建
    S5P4418开发板介绍
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477358.html
Copyright © 2020-2023  润新知