• BZOJ-1011&洛谷P3198遥远的行星【HNOI2008】-玄学题之分块


    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge

    洛谷:时间限制1.00s 内存限制125.00MB

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1011

    洛谷:https://www.luogu.com.cn/problem/P3198

    Description

      直线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=
    Mi*Mj/(j-i) 其中A为很小的常量,故直观上说每颗行星都只受到距离遥远的行星的作用。请计算每颗行星的受力
    ,只要结果的相对误差不超过5%即可.

    Input

      第一行两个整数N和A. 1<=N<=10^5.0.01< a < =0.35,接下来N行输入N个行星的质量Mi,保证0<=Mi<=10^7

    Output

      N行,依次输出各行星的受力情况

    Sample Input

    5 0.3
    3
    5
    6
    2
    4

    Sample Output

    0.000000
    0.000000
    0.000000
    1.968750
    2.976000

    HINT

      精确结果应该为0 0 0 2 3,但样例输出的结果误差不超过5%,也算对


    如果数据范围小一些的话就很好办,就是简单的暴力,我们先写出来:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int mac=1e5+10;
    
    int m[mac];
    double f[mac];
    
    int main()
    {
        int n;
        double a;
        scanf ("%d%lf",&n,&a);
        for (int i=1; i<=n; i++)
            scanf("%d",&m[i]);
        for (int i=1; i<=n; i++) f[i]=0;
        for (int i=1; i<=n; i++){
            for (int j=1; j<=(int)i*a; j++){
                f[i]+=1.0*m[i]*m[j]/(1.0*i-j);
            }
        }
        for (int i=1; i<=n; i++)
            printf("%f
    ",f[i]);
        return 0;
    }

    然后交一发就会发现只过了2个点。

    然后。。。怎么优化,发现好像不会,就无耻地打开了题解。。。神TM近似解。

    按照题解的算法来讲就是分块,由于有5%的误差,所以我们可以用块的中点来代替整个块,块越大误差越大,那么块中的答案就是$frac {m[i] imes sum_{j=l}^{r}m[j]} {i-(l+r)/2}$

    数列分块的具体方法在我以前的博客中有过说明:https://blog.csdn.net/qq_43906000/article/details/100435873

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    
    const int mac=1e5+10;
    const double esp=1e-5;
    
    int m[mac],id[mac],L[mac],R[mac];
    ll sum[mac];
    
    double solve(int r,int p)
    {
        int rr=id[r];
        double ans=0;
        if (rr==1){
            for (int i=1; i<=r; i++)
                ans+=(double)m[i]*m[p]/(p-i);
        }
        else{
            for (int i=1; i<=rr-1; i++)
                ans+=(double)m[p]*sum[i]/(p-(double)(R[i]+L[i])/2);
            for (int i=L[rr]; i<=r; i++)
                ans+=(double)m[p]*m[i]/(p-i);
        }
        return ans;
    }
    
    int main()
    {
        int n;
        double a;
        scanf ("%d%lf",&n,&a);
        for (int i=1; i<=n; i++)
            scanf("%d",&m[i]);
        int len=pow(n,0.35)+esp;
        int t=n/len;
        for (int i=1; i<=t; i++){
            L[i]=(i-1)*len+1;
            R[i]=i*len;
        }
        if (R[t]<n) t++,L[t]=R[t-1]+1,R[t]=n;
        for (int i=1; i<=t; i++)
            for (int j=L[i]; j<=R[i]; j++)
                id[j]=i,sum[i]+=m[j];
        for (int i=1; i<=n; i++){
            int r=i*a+esp;
            double ans=solve(r,i);
            printf("%lf
    ",ans);
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    android中图型的阴影效果(shadow-effect-with-custom-shapes)
    git的经常使用命令
    C# vs Java
    Android-68-Tomcat各种启动错误的解决的方法,如:Exception in thread &quot;Thread-6&quot; NoClassDefFoundError,Document base E:
    Java高级程序猿技术积累
    Floodlight下发流表过程分析
    Maximal Rectangle [leetcode] 的三种思路
    C++实现顺序栈的基本功能
    ZOJ 1654 Place the Robots(最大匹配)
    [2-SAT] poj 3207 Ikki&#39;s Story IV
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/12217361.html
Copyright © 2020-2023  润新知