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

来源:互联网 发布:穆如寒江小说知乎 编辑:程序博客网 时间:2024/04/29 19:51

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;}






0 0
原创粉丝点击