Description
Alice得到了一个整数, 她将其视作长度为n的字符串S。为了好玩,她进行了k次如下操作:
1) 随机选取两个不同的位置x和y(即每次操作, {<x, y> | 1<=x < y <=n}中每个元素都有相同的概率被选到)
2) 交换数位S[x]和数位S[y]
为了自虐,在Alice恶搞之后,Bob会随机一个子串(即对于任意子串都有相同概率被选到),然后他想知道他选出的子串中各个位置数字之和的期望为多少。聪明的Bob想出了一个很好的方法来解决这个问题,那就是把这个问题交给你。Bob会告诉你S和k,你需要告诉他期望。
1) 随机选取两个不同的位置x和y(即每次操作, {<x, y> | 1<=x < y <=n}中每个元素都有相同的概率被选到)
2) 交换数位S[x]和数位S[y]
为了自虐,在Alice恶搞之后,Bob会随机一个子串(即对于任意子串都有相同概率被选到),然后他想知道他选出的子串中各个位置数字之和的期望为多少。聪明的Bob想出了一个很好的方法来解决这个问题,那就是把这个问题交给你。Bob会告诉你S和k,你需要告诉他期望。
Input
一行,包含字S和k。
Output
一行,一个实数。当你的输出和标准答案的差距少于10^-6时,被认为是正确的。
Solutions
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 var 2 a:array [0..1000001] of integer; 3 s:ansistring; 4 k,sum,ll:longint; 5 qi,ans,tk:real; 6 procedure init; 7 var 8 i,p:longint; 9 begin 10 readln(s); 11 p:=pos(' ',s); ll:=length(s); 12 val(copy(s,p+1,ll-p),k); 13 sum:=0; ll:=p-1; 14 for i:=1 to ll do 15 begin 16 a[i]:=ord(s[i])-48; 17 sum:=sum+a[i]; 18 end; 19 end; 20 21 procedure main; 22 var 23 i:longint; 24 o,p:real; 25 begin 26 tk:=1; qi:=(ll-1)*ll/2; 27 for i:=1 to k do 28 tk:=tk*(1-(ll-1)/qi)+(1-tk)/qi; 29 ans:=0; 30 for i:=1 to ll do 31 ans:=(i*(ll-i+1)/(ll*(ll+1)/2))*(a[i]*tk+(sum-a[i])/(ll-1)*(1-tk)); 32 writeln(ans:0:8); 33 end; 34 35 begin 36 init; 37 main; 38 end.