• 【BZOJ】1011: [HNOI2008]遥远的行星(近似)


    http://www.lydsy.com/JudgeOnline/problem.php?id=1011

    题意:$f[i] = sum_{j=1}^{i-1} frac{M[i]M[j]}{i-j}$,求$1<=n<=10^5$的所有$f[i]$

    orz 神题啊。。。

    第一次做这种近似的题orz

    首先n^2肯定是不可做的。。

    然后看了题解。。

    好神

    首先得到$f[i]$表示第$i$个的能量, $g[i]$为题目给的$A*i$

    $$f[i]=M_i imes sum_{j=1}^{g[i]} frac{M_j}{i-j}$$

    而我们设$a=i+T$

    $$f[a]=M_a imes sum_{j=1}^{g[a]} frac{M_j}{a-j}$$

    $$ = M_a( sum_{j=1}^{g[a-T]}frac{M_j}{a-j}+sum_{j=g[a-T]+1}^{g[a]} frac{M_j}{a-j}) $$

    $$ = M_a( sum_{j=1}^{g[a-T]}frac{M_j}{a-T-j} imes frac{a-T-j}{a-j}+sum_{j=g[a-T]+1}^{g[a]} frac{M_j}{a-j}) $$

    再利用数学上的技巧,可得到近似值:

    $$ approx M_a( frac{f[a-T]}{M_{a-T}} imes frac{a-T-frac{g[a-T]}{2}}{a-frac{g[a-T]}{2}}+sum_{j=g[a-T]+1}^{g[a]} frac{M_j}{a-j}) $$

    右边数据小暴力搞就行了,t我一开始开1000wa了。。。。开100才a。。。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    typedef long long ll;
    #define pii pair<int, int>
    #define mkpii make_pair<int, int>
    #define pdi pair<double, int>
    #define mkpdi make_pair<double, int>
    #define pli pair<ll, int>
    #define mkpli make_pair<ll, int>
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << (#x) << " = " << (x) << endl
    #define error(x) (!(x)?puts("error"):0)
    #define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
    #define printarr1(a, b) for1(_, 1, b) cout << a[_] << '	'; cout << endl
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const double eps=1e-8;
    const int N=1e5+10, T=100;
    int g[N], n;
    double k, ans[N], m[N];
    int main() {
    	read(n); scanf("%lf", &k);
    	for1(i, 1, n) scanf("%lf", &m[i]);
    	for1(i, 1, n) g[i]=(int)(floor(k*(double)i)+eps);
    	for1(i, 1, min(n, T)) {
    		for1(j, 1, g[i]) ans[i]+=m[j]/(i-j);
    		ans[i]*=m[i];
    	}
    	for1(i, min(n, T)+1, n) {
    		int pre=i-T;
    		for1(j, g[pre]+1, g[i]) ans[i]+=m[j]/(i-j);
    		ans[i]+=ans[pre]*(pre-g[pre]/2.0)/m[pre]/(i-g[pre]/2.0);
    		ans[i]*=m[i];
    	}
    	for1(i, 1, n) printf("%.6f
    ", ans[i]+eps);
    	return 0;
    }
    

      


    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%,也算对

    Source

     
  • 相关阅读:
    django中ckeditor富文本编辑器使用
    xadmin安装
    RabbitMQ应用示例
    windows下安装RabbitMQ
    第四章 面向对象
    第三章 模块
    git简单使用
    python中的装饰器
    Python 使用 argparse 开发命令行工具/获取命令行参数/子命令实现
    自动化运维工具 Ansible 安装、配置及使用
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4092915.html
Copyright © 2020-2023  润新知