Atcoder AGC007C : Pushing Balls

传送门

题解:

把每个球的操作一次后的期望具体写出来,发现还是一个等差数列,猜个结论:把之后的局面用这个等差数列算是等价的(其实应该也不难理解)。

假设现在等差数列为 ( d , x ) ,我们可以发现:
操作一次后:
d = ( ( 2 n 2 ) d + ( d + x ) + ( 3 d + 6 x ) ) 2 n (其实就是1距离左边的期望距离)

s u m = s u m ( d + ( d + x ) + ( ( 2 n 2 ) x + d ) + ( ( 2 n 1 ) x + d ) ) 2 n (只有两种操作会引起和的改变)

根据 s u m d 就可以轻松的算出 x 了,递归到长度为1即可,时间复杂度 O ( n )

#include <bits/stdc++.h>
using namespace std;
typedef long double DB;

DB d,x,n;
int main() {
    cin>>n>>d>>x; DB ans=0;
    for(int i=n;i>=1;i--) {
        DB sum=(d*2*n+n*(2*n-1)*x);
        ans+=sum/2/n;
        DB d2=(d*(2*n-2)+d+2*x+3*d+3*x)/2/n;
        sum=sum-(4*d+4*n*x-2*x)/2/n;
        n-=1;
        DB x2=(sum-2*n*d2)/n/(2*n-1);
        d=d2; x=x2;
    } printf("%.15f\n",(double)ans);
}

猜你喜欢

转载自blog.csdn.net/qq_35649707/article/details/80857193