bzoj1011

1011: [HNOI2008]遥远的行星

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
Submit: 2480  Solved: 895

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

题意:题目意思明了,给一个数列M[1....n],每一位都有一个值,第 i 个值为 所有 (j <= i * A ),M[ i ]*M[ j ] / (i - j) 的和

分析:显然有一个O(n^2)的做法,即对每个点 i,都暴力枚举 1... floor( i * A )的点求和,

但注意到误差最多有5%,所以我们可以不求精确值,考虑放缩思想,、把1....floor( i * A)分解成多段,每段都可以简单的求和,并且误差在5%以内

显然,我们首先可以把M[i]提取公因数,第 i 个值为 M[i] * (    所有M[j] / (i  - j)的和  ( 1 <= j <= i * A)      )

即 M[i]*( M[j]/(i-j) + M[j-1]/(i-j+1) + M[j-2]/(i-j+2) + .... + M[1]/(i-1) )

一个显然的放缩为 对于一段 j, j-1, j-2, ......,j-k,放大为(M[j] + M[j-1] + M[j-2] + ..... + M[j-k]) / (i - j)

为使误差小于5%,我们令

M[j-k]/(i - j)   -    M[j-k]/(i - j + k)  <= M[j-k]/(i - j + k) * 5%

这样必定有误差小于5%

我们令x = i - j,约掉M[j+k],变形的
1/x   -    1/(x+k) <= 1 / (x+k) * 5%

(x+k) - x <= x * 5%

k <= x/20

即这一段最长为 j ..... j-(i-j)/20

则下一段起点为 j-(i-j)/20-1,这样一段段分下去,一直到分完 i*A ..... 1

如果这样分组,最多有多少段?

我们去极限情况,n = 100000,A = 0.35

这样得到也不超过10段,时间复杂度完全可以接受

综上所述,本题得解

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <deque>
 6 #include <vector>
 7 #include <queue>
 8 #include <iostream>
 9 #include <algorithm>
10 #include <map>
11 #include <set>
12 #include <ctime>
13 using namespace std;
14 typedef long long LL;
15 typedef double DB;
16 #define For(i, s, t) for(int i = (s); i <= (t); i++)
17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--)
18 #define MIT (2147483647)
19 #define INF (1000000001)
20 #define MLL (1000000000000000001LL)
21 #define sz(x) ((int) (x).size())
22 #define clr(x, y) memset(x, y, sizeof(x))
23 #define puf push_front
24 #define pub push_back
25 #define pof pop_front
26 #define pob pop_back
27 #define ft first
28 #define sd second
29 #define mk make_pair
30 inline void SetIO(string Name) {
31     string Input = Name+".in",
32     Output = Name+".out";
33     freopen(Input.c_str(), "r", stdin),
34     freopen(Output.c_str(), "w", stdout);
35 }
36
37 const int N = 100010;
38 const DB Eps = 1e-6;
39 int n;
40 DB A, M[N];
41 DB Sum[N], Ans[N];
42
43 inline void Input() {
44     scanf("%d%lf", &n, &A);
45     For(i, 1, n) scanf("%lf", &M[i]);
46 }
47
48 inline void Solve() {
49     For(i, 1, n) Sum[i] = Sum[i-1]+M[i];
50
51     For(i, 1, n) {
52         int S = (int) floor(1.0*i*A);
53         DB Cnt = 0.0;
54         while(S) {
55             int K = i-S;
56             int D = K/20;
57             int _K = min(K+D, i-1);
58             int _S = i-_K-1;
59             Cnt += (Sum[S]-Sum[_S])/((DB) K);
60             S = _S;
61         }
62         Ans[i] = Cnt*M[i];
63     }
64
65     For(i, 1, n) printf("%.6lf\n", Ans[i]);
66 }
67
68 int main() {
69     SetIO("1011");
70     Input();
71     Solve();
72     return 0;
73 }

时间: 2024-11-06 03:45:01

bzoj1011的相关文章

【反演复习计划】【bzoj1011】zap-queries

快三个月没做反演题了吧-- 感觉高一上学期学的全忘了-- 所以还得从零开始学推式子. # bzoj1011 标签(空格分隔): 未分类 --- 原题意思是求以下式子:$Ans=\sum\limits_{i=1}^{a}\sum\limits_{i=1}^{b}[gcd(i,j)==k]$首先把k拿下来,得到$Ans=\sum\limits_{i=1}^{a/k}\sum\limits_{i=1}^{b/k}[gcd(i,j)==1]$然后考虑mobius函数的性质:$\sum\limits_{d

[BZOJ1011] [HNOI2008] 遥远的行星

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行

【BZOJ1011】【HNOI2008】遥远的行星

这次不看别人代码基本上写不出来,这属于偏题系列把,奇奇怪怪突然出戏的题 原题: 直线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=Mi*Mj/(j-i) 其中A为很小的常量,故直观上说每颗行星都只受到距离遥远的行星的作用.请计算每颗行星的受力,只要结果的相对误差不超过5%即可. 1<=N<=10^5.0.01< a < =0.35,0<=Mi<=10^7 引用chty的一句话:“如何提高智商

【bzoj1011】[HNOI2008]遥远的行星

#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<queue> using namespace std; typedef long double LD; #define N 100010 long double a; int n,T=50;

【BZOJ1011】【HNOI2008】遥远的行星 根据所允许的误差进行模糊DP

题解: 暴力肯定过不了, 但是我们可以把除数模糊化一下,让一部分数统一用一个除数,这样就可以在5%误差以内快速出解了. 额,但是前面一大段的动规值需要暴力求,要不就很难满足5%了.. 给个神博客http://hi.baidu.com/zeonsgtr/item/789da6f2838a3dc742c36ab7 再贴个代码 #include <cmath> #include <cstdio> #include <cstring> #include <algorith

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

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为很小的常量,故直观上说每颗行星都只受到距离遥远的行星的作用.请计算每颗行星的

bzoj刷题(shui)记录

放假刷了一个月的水题,集中写一下题解吧. bzoj1858:线段树随便维护一下. code bzoj2705:莫比乌斯反演裸题. code bzoj1202:并查集,但是我写了一种跟floyd很像的奇怪的东西. code bzoj1072:暴力. bzoj2431:dp f[i][j]=sum(f[i-1],[k]) code bzoj3505:组合数学. code bzoj1058:两棵平衡树. code bzoj1922:维护两个距离,然后更新答案. code bzoj1009:之前写过题解

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ

#11:假日将尽的挣扎——6

cf818A 1 #include <bits/stdc++.h> 2 #define ll __int64 3 using namespace std; 4 5 ll n, k; 6 7 int main() { 8 cin >> n >> k; 9 ll a = n / 2 / (k+1); 10 ll b = k * a; 11 printf("%I64d %I64d %I64d\n", a, b, n-a-b); 12 return 0; 1