1 条题解

  • 0
    @ 2026-8-22 22:15:41

    我们发扬人类智慧!

    首先我们注意到题目中有一句话:

    • 只要结果的相对误差不超过 5% 即可。

    因此我们考虑分块,我们令块长 k=50k=50。然后用一个前缀和数组预处理出每一块内的质量和。

    分母的话我们就不要用 jij-i 了,我们可以用这一块的中点,这样我们就可以 O(1)O(1) 算出分母了,由于我们的块长不会很大,精度也可以保证。

    然后不满一块的部分我们直接暴力计算即可。

    时间复杂度:玄学(话说人类智慧题都这个复杂度吧)。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    double m[N],sum[N],f[N];
    int main(){
    	int n,k=50;double v;
    	scanf("%d%lf",&n,&v);
    	for(int i=1;i<=n;i++){
    		scanf("%lf",&m[i]);
    		sum[i]=sum[i-1]+m[i];
    	}
    	for(int j=1;j<=n;j++){
    		for(int i=1;i<=(int)(v*j/k);i++){
    			f[j]=f[j]+m[j]*(sum[i*k]-sum[(i-1)*k])/(j-((i-1)*k+1+i*k)/2.0);
    		}
    		for(int i=(int)(v*j/k)*k+1;i<=v*j;i++){
    			f[j]=f[j]+m[i]*m[j]/(j-i);
    		}
    	}
    	for(int i=1;i<=n;i++){
    		printf("%.6lf\n",f[i]);
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    2664
    时间
    1000ms
    内存
    125MiB
    难度
    6
    标签
    递交数
    38
    已通过
    14
    上传者