codeforces 846F Random Query

F. Random Query
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given an array a consisting of n positive integers. You pick two integer numbers l and r from 1 to n, inclusive (numbers are picked randomly, equiprobably and independently). If l > r, then you swap values of l and r. You have to calculate the expected value of the number of unique elements in segment of the array from index l to index r, inclusive (1-indexed).

Input
The first line contains one integer number n (1 ≤ n ≤ 106). The second line contains n integer numbers a1, a2, ... an (1 ≤ ai ≤ 106) — elements of the array.

Output
Print one number — the expected number of unique elements in chosen segment.

Your answer will be considered correct if its absolute or relative error doesn't exceed 10 - 4 — formally, the answer is correct if , where x is jury's answer, and y is your answer.

Examples
input
2
1 2
output
1.500000
input
2
2 2
output

1.000000

题意:给定一个序列a,求任意选择两个数L,R  求区间(L,R)  (L>R则交换)  中出现数的数的种类个数 的期望。

分析: 每一个数ai对答案的贡献值就是 作为ai他是在那些区间是第一次出现的 , 对于 一个数 ai 求 他对那些L,R是有贡献的。我们只要 求出 前一个值为ai的出现位置L[ai],则 他的贡献 有( i-L[ai] ) * ( n-i+1 )*2 - 1

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<time.h>
#include<vector>
const int maxn = 1e6;
typedef long long ll;
using namespace std;
ll n;
int a[maxn+5];
int l[maxn+5];
void solve()
{
   ll cnt;
   double tot=0;
   memset(l,0,sizeof(l));
   for(int i=1;i<=n;i++)
   {
      cnt = (i-l[a[i]])*(n-i+1)*2-1;
      tot+=cnt*1.0;
      l[a[i]] = i;
   }
   double ans = tot*1.0/n/n;
   printf("%.6lf\n",ans);
}
int main()
{
    while(~scanf("%I64d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        solve();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值