题意:给你一个长为n的数组,随机选择两个数l和r,然后问你[l,r]中不同元素的个数的期望是多少?(l大于r的话,翻转l和r)
题解:因为l和r无大小关系设定,因此选择两个数的概率为1/n/n,如果求所有区间肯定不好求,因此我们考虑每种元素对答案的贡献,我们知道对于某个区间,当前元素不管出现多少次都只能算一次,因此对于每个元素的贡献,答案一定是区间总个数-不包含该种元素的区间个数。。然后加在一起就是答案。
#include<vector>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll long long
vector<int>q[1000005];
ll n,a[1000005],b[1000005],ans;
int main(void)
{
scanf("%lld",&n);
for(int i=1;i<=1000000;i++)
q[i].push_back(0);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
q[a[i]].push_back(i);
b[a[i]]=1;
}
for(int i=1;i<=1000000;i++)
q[i].push_back(n+1);
for(int i=0;i<=1000000;i++)
{
if(b[i]==0) continue;
ans+=n*n;
for(int j=1;j<q[i].size();j++)
ans-=(ll)(q[i][j]-q[i][j-1]-1)*(q[i][j]-q[i][j-1]-1);
}
printf("%.10f\n",1.0*ans/n/n);
return 0;
}