码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1011([HNOI2008]遥远的行星-估计误差)

时间:2015-01-18 02:06:53      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:

1011: [HNOI2008]遥远的行星

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
Submit: 2134  Solved: 755
[Submit][Status]

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


原题要求所有的f[i]=mi*mj/(i-j) (j<=Ai<=0.35i)

小数据可以大暴力,

大数据可以估计,因为j相对i来说很小 所以 f[i]=∑mi*mj/(i-j)=mi/(i-t)*∑mj 其中(i-t)取(i-j)的平均值



#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (100000+10)
#define MAXAJ (35000)
#define MAXMi (10000000)
#define eps (1e-6) 
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n;
double a[MAXN],s[MAXN],f[MAXN]={0.0};
double A;
int main()
{
//	freopen("bzoj1011.in","r",stdin);
	cin>>n>>A;
	a[0]=s[0]=0;For(i,n) {scanf("%lf",&a[i]);s[i]=a[i]+s[i-1];}
	
	const int Q=min(2000,n);
	//2000以内暴力 
	For(i,Q)
	{
		double maxj=A*(double)i+eps;
		For(j,maxj)
			f[i]+=a[j]/(double)(i-j);
		f[i]*=a[i];
	} 
	//2000以上a[i]*a[j]/(j-i) 中j取平均值 
	Fork(i,Q+1,n)
	{
		double maxj=A*(double)i+eps;
		int Ai=floor(maxj);
		f[i]=a[i]*s[Ai]/(double)(i-(1+Ai)/2);
	}
	
	For(i,n) printf("%.6lf\n",f[i]);
	 
	
	return 0;
}






BZOJ 1011([HNOI2008]遥远的行星-估计误差)

标签:

原文地址:http://blog.csdn.net/nike0good/article/details/42821959

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!