CF205E-Little Elephant and Furik and Rubik

CF205E-Little Elephant and Furik and Rubik

Description

Little Elephant loves Furik and Rubik, who he met in a small city Kremenchug.

The Little Elephant has two strings of equal length a and b, consisting only of uppercase English letters. The Little Elephant selects a pair of substrings of equal length — the first one from string a, the second one from string b. The choice is equiprobable among all possible pairs. Let’s denote the substring of a as x, and the substring of b — as y. The Little Elephant gives string x to Furik and string y — to Rubik.

Let’s assume that f(x,y) is the number of such positions of i (1i|x| ), that xi=yi (where |x| is the length of lines x and y, and xi,yi are the i-th characters of strings x and y, correspondingly). Help Furik and Rubik find the expected value of f(x,y) .

Input

The first line contains a single integer n (1n2·105 ) — the length of strings a and b. The second line contains string a, the third line contains string b. The strings consist of uppercase English letters only. The length of both strings equals n .

Output

On a single line print a real number — the answer to the problem. The answer will be considered correct if its relative or absolute error does not exceed 106 .

題解

E(n)=Pif(x,y)

Pi 表示每種字串x,y 出現的可能

同時這個等式也可以表示成如下的形式:

E(n)=Pij=0lxj==yj

xj==yj 爲1否則爲0

l 爲子串x 的長度

然後轉化爲

E(n)=i=0lPi(xj==yj)

因爲每種字串的出現的可能都是相等的

P1==P2==...Pn

所以

E(n)=Pj=0lxj==yj

我們可以看出本質上題目要求的就是所有子串中xi==yi 的個數

與概率無關

那麼我們可以枚舉字符c ,看能構造多少個子串xi==cyi==c

這裏我們採用

比如說祖串X:abav,Y:bacd ,對於Y2 也就是a 來說,我們可以匹配X1 ,因爲X1 爲第一X 第一個字符,所以無法向左擴展,向右可以擴展2個長度,我們還可以匹配X3 ,向左擴展1個長度,向右擴展1個長度,那麼對於a 來說,總共可以構造出的字串的個數爲,13+22 個。

但是我們發現這樣還是沒有辦法解決問題,直接搜索匹配字符的複雜度爲O(N2) 的,對於2105 的數據肯定超時,那麼如何優化時間複雜度呢?

經過大仙的提醒我們可以觀察到,對於Yi ,對於在X串相同位置之前的匹配的字符Xj 向左擴展的長度都是有Xj 決定的即爲j,向右擴展的長度都是由Yi 決定的即爲i ,對於Yi 之後的字符我們能夠找到類似的性質,那麼我們就可以預處理j(Yj==Xi,j<=i) ,和j(Yj==Xi,j>=i) ,然後通過O(N) 的複雜度求解。

PS:注意Xi 不要算重複了

代碼

/*********************************
Author: Toudsour
Created Time: 六  8/29 14:56:25 2015
File Name:CF205E.cpp
*********************************/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char StrA[200100];
char StrB[200100];
long long CountP[26][200100];
long long CountE[26][200100];
int main()
{
    int  N;
    scanf("%d",&N);
    scanf("%s",&StrA[1]);
    scanf("%s",&StrB[1]);
    for(int i=1;i<=N;i++)
    {
        int A=StrA[i]-'A';
        CountP[A][i]=i;
    }
    for(int i=N;i>=1;i--)
    {
        int A=StrA[i]-'A';
        CountE[A][i]=N+1-i;
    }
    //for(int i=1;i<N;i++)
    //    cout<<CountP[0][i]<<" ";
    //cout<<endl;
    for(int i=1;i<=N;i++)
        for(int j=0;j<26;j++)
            CountP[j][i]+=CountP[j][i-1];
    for(int i=N-1;i>=1;i--)
        for(int j=0;j<26;j++)
            CountE[j][i]+=CountE[j][i+1];
    double Sum=0;
    for(int i=1;i<=N;i++)
    {
        //cout<<i<<endl;
        int A=StrB[i]-'A';
        Sum+=CountP[A][i]*(N+1-i);
        //cout<<(N-i+1)<<" "<<CountP[A][i]<<endl;
        Sum+=CountE[A][i+1]*i;
        //cout<<i<<" "<<CountE[A][i]<<endl;
    }
    double Ans=Sum;
    double Temp=N;
    Ans=Ans/(Temp*(Temp+1)*(2*Temp+1)/6);
    printf("%.9f\n",Ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章