【概率论,期望,观察,高斯消元】P5516 [MtOI2019]小铃的烦恼
给定一个长度为
n 的字符串s ,每次操作选择两个不同的下标a,b ,将s_a 变为s_b ,求使得整个s 完全相同的期望操作次数。
我们考虑全期望公式,答案显然可以表示为
我们先考虑如何求出
显然这个东西并不是处处相等的,我们考虑它和什么有关,暴力的想法是记录整个串每一位是否
容易发现事实上并不需要这么多状态,它只和当前串中
整理得
显然有
现在我们的问题就是求出
我们还是考虑记录
设
显然
设
这个看起来就不是很好归纳了,我们考虑直接对它跑一个高斯消元,但是这是
复杂度瓶颈在于输入,若不输入全 1
矩阵,则时空复杂度均为
const int N=2e3+5;
char s[N];
int n,c[26];
struct rs{
db x,y;
rs operator*(const db&p)const{return rs{x*p,y*p};}
rs operator-(const db&p)const{return rs{x,y-p};}
rs operator-(const rs&p)const{return rs{x-p.x,y-p.y};}
}f[N];
int main(){
scanf("%s",s+1),n=strlen(s+1);
for(int i=1;i<=n;i++)c[s[i]-'A']++;
f[1]=rs{1,0};
for(int i=1;i<n;i++){
db p=i,x=n;
f[i+1]=f[i]*((p*2)/(p+1))-f[i-1]*((p-1)/(p+1))-x*(x-1)/(p+1)/(x-p);
}
db f1=(-f[n].y)/f[n].x,as=0;
for(int i=0;i<26;i++)as+=((db)c[i]/n)*(f[c[i]].x*f1+f[c[i]].y);
printf("%.1lf",as);
return 0;
}