Codeforces 846F

来源:互联网 发布:什么是无约束优化问题 编辑:程序博客网 时间:2024/05/17 22:36


F. Random Query

time limit per test 2seconds

memory limit per test     256megabytes


You are given an arraya consisting ofn positive integers. You pick twointeger numbersl andr from1 ton, inclusive (numbers are picked randomly, equiprobably andindependently). Ifl > r, then you swap values of l andr. You have to calculate the expectedvalue of the number of unique elements in segment of the array from index l to indexr, inclusive (1-indexed).

Input

The first line contains one integer numbern(1 ≤ n ≤ 106). The second line contains n integer numbersa1,a2, ...an(1 ≤ ai ≤ 106) — elements of the array.

Output

Print one number — the expected number of unique elements inchosen segment.

Your answer will be considered correct if its absolute or relative error doesn'texceed10 - 4 — formally, the answer iscorrect if , where x is jury's answer, andy is your answer.

Examples

Input

2
1 2

Output

1.500000

Input

2
2 2

Output

1.000000

 

【题意】


给出n个数,需要计算从1~n中选出两个数(可以相同)x,y,令l=min(x,y),r=max(x,y),区间[l,r]内不同数个数的期望值。


【思路】


显然期望值为所有情况(共n*n种)的不同数个数和,再除以情况数。


那么我们要做的便是在限制时间内算出所有情况的不同数个数和。


由于x,y的大小不确定,但是其实无论谁大谁小对结果的影响不大,所以我们先固定x<=y。


假设我们现在在考虑第i个数,且已经算出了前(i-1)个数所有区间的不同数个数。


  1. 如果它他前面没有与它相同的数,那么它的贡献为使每个区间都多一个数,即[1,i],[2,i],[3,i],[4,i]....[i,i],

  2. 如果它前面有与之相同的数,前一次出现的位置为pos,那么对于区间[1,i],[2,i]...[pos,i]来说不同数的个数并没有改变,当然剩下的区间由于之间不包括这个数,每个区间不同数的个数会加一。


由上面的分析,我们可以推出:假设前(i-1)个的所有区间(固定x<=y)不同数个数和为sum[i-1],那么前i个的所有区间(固定x<=y)不同数个数和为sum[i-1]+i-pre[i],其中pre[i]为第i个数前一次出现的位置(没有则为0)。


然后考虑x,y大小的任意性,每个数的贡献即为sum[i]*2-1,减一的原因为当x,y相等时只有一种情况。


于是扫一遍累加结果再除以情况数即可。


#include <cstdio>#include <cmath>#include <map>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define rush() int T;scanf("%d",&T);while(T--)typedef long long ll;const int maxn = 1000005;const ll mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-6;int a[maxn],pre[maxn];int main(){    int n,x;    while(~scanf("%d",&n))    {        mst(pre,0);        ll ans=0;        ll temp=0;        for(int i=1;i<=n;i++)        {            scanf("%d",&x);            temp+=i-pre[x];            pre[x]=i;            ans+=(ll)temp*2-1;        }        printf("%.6f\n",ans*1.0/n/n);    }    return 0;}








原创粉丝点击