【BZOJ1011】遥远的行星

第一次见到拿误差做文章的题,世界观又一次刷新。

看到这题的第一感觉是前两天做过的力,所以一来就往FFT上想。。。然并卵,边界死活不会处理

看了标解顿时有婊人的冲动。。。

对于那些比较大的n(以2000为界比较合适),我们发现不同1/(i-j)之间的差距极小,因此我们用1/(i-(i*A)/2)来代替所有的分母,加上前缀和就变成O(1)了。

/************************************************************** 
    Problem: 1011 
    User: RicardoWang 
    Language: C++ 
    Result: Accepted 
    Time:1580 ms 
    Memory:3616 kb 
****************************************************************/
  
#include<cstdlib> 
#include<cstdio> 
#include<iostream> 
#include<cstring> 
#include<cmath> 
#include<algorithm> 
#include<vector> 
#include<queue> 
using namespace std; 
#define maxn 100005 
int n; 
double a[maxn],A,m[maxn]; 
void _read(int &x) 
{ 
    x=0; char ch=getchar(); 
    while(ch<'0'||ch>'9')ch=getchar(); 
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} 
    return ; 
} 
void _readLL(long long &x) 
{ 
    x=0; char ch=getchar(); 
    while(ch<'0'||ch>'9')ch=getchar(); 
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} 
    return ; 
} 
void Init() 
{ 
    long long x; _read(n); 
    scanf("%lf",&A); 
    for(int i=1;i<=n;i++){_readLL(x); m[i]=x;a[i]=a[i-1]+m[i];} 
    return ; 
} 
double g[maxn],eps=1e-7; 
double fabs(double x) 
{ 
    return x>0? x:-x; 
} 
int main() 
{ 
    //freopen("in.txt","r",stdin); 
    Init(); 
    int j; 
    memset(g,0,sizeof(g)); 
    for(int i=1;i<=2000 && i<=n;i++) 
    { 
        j=(int)(A*(double)i);  
        if(fabs(A*(double)i-(double)(j+1))<=eps)j++; 
        for(int k=1;k<=j;k++)g[i]+=m[i]*m[k]/(double)(i-k); 
    } 
    for(int i=2001;i<=n;i++) 
    { 
        j=(int)(A*i); 
/*      while(j>10000) 
        { 
            g[i]+=m[i]*(a[j]-a[j-10000])/(double)(i-j-5000); j-=10000; 
        } 
        while(j>1000) 
        { 
            g[i]+=m[i]*(a[j]-a[j-1000])/(double)(i-j-500); j-=1000; 
        }*/
        g[i]+=m[i]*(a[j])/(double)(i-j/2); 
    } 
    for(int i=1;i<=n;i++) 
    { 
        printf("%lf\n",g[i]); 
    } 
    return 0; 
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值