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 (1 ≤ i ≤ |x| ), thatxi = yi (where|x| is the length of lines x and y, andxi,yi are the i-th characters of strings x and y, correspondingly). Help Furik and Rubik find the expected value off(x, y) .
Input
The first line contains a single integer n (
1 ≤ n ≤ 2·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 equalsn .
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
10−6 .
題解
同時這個等式也可以表示成如下的形式:
然後轉化爲
因爲每種字串的出現的可能都是相等的
即
所以
我們可以看出本質上題目要求的就是所有子串中
與概率無關
那麼我們可以枚舉字符
這裏我們採用
比如說祖串
但是我們發現這樣還是沒有辦法解決問題,直接搜索匹配字符的複雜度爲
經過大仙的提醒我們可以觀察到,對於
PS:注意
代碼
/*********************************
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;
}