题解
- k次交换后,ans=每一位的期望值*每一位被选出的概率
- 显然第i位被选出的概率=包含i的子串数/总子串数=i*(n-i+1)/(n*(n+1)/2)
- 那如何求k次交换后每一位的期望值?
- 我们假设最初第i位为ai,p次交换后第i位仍然等于ai的概率是x,那么p+1交换后第i为仍然等于ai的概率是x*(1-(n-1)/q))+(1-x)/q
- 其中q=n*(n-1)/2
- 接下来有一个性质:
- 如果第i位不为ai,那么第i位是a中其他任何数的概率都是一样的(交换的随机性决定的)
- 因此如果k次交换后,第i位为ai的概率是x,那么第i位的期望值=ai*x+(sum-ai)/(n-1)*(1-x)
- 以上是题解的说法
代码
1 #include <cstdio>
2 #include <iostream>
3 #include <algorithm>
4 #include <cstring>
5 using namespace std;
6 char s[1000010];
7 int k,n,a[1000010],sum;
8 double x,q,a1,a2,ans;
9 int main()
10 {
11 scanf("%s %d",s,&k);
12 n=strlen(s);
13 for (int i=1;i<=n;i++)
14 {
15 a[i]=s[i-1]-'0';
16 sum+=a[i];
17 }
18 x=1.0; q=(n-1.0)*n/2.0;
19 for (int i=1;i<=k;i++) x=x*(1.0-(n-1.0)/q)+(1.0-x)/q;
20 for (int i=1;i<=n;i++)
21 {
22 a1=i*(double)(n-i+1.0)/(double)(n*(n+1.0)/2.0);
23 a2=(double)a[i]*x+(double)(sum-a[i])/(double)(n-1.0)*(1.0-x);
24 ans+=a1*a2;
25 }
26 printf("%.9lf",ans);
27 return 0;
28 }