此题我想了半个点,得出一个重要结论:我除了暴力以外啥也想不出来。
然后看了一下题解,彻底懵了……
对于每一个数 j,令x = j * a,因为题中说了一句“只要结果的相对误差不超过5%即可”,所以用分块解决这[1, x]。正好一块的部分[L, R]就都除以 j - (L +R) / 2……没错中位数……多出来的部分就暴力统计……【真德秀】。(块大小100左右就行)
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter printf(" ") 13 #define space printf(" ") 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const int eps = 1e-8; 19 const int maxn = 1e5 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) 26 { 27 ans = ans * 10 + ch - '0'; ch = getchar(); 28 } 29 if(last == '-') ans = -ans; 30 return ans; 31 } 32 inline void write(ll x) 33 { 34 if(x < 0) x = -x, putchar('-'); 35 if(x >= 10) write(x / 10); 36 putchar(x % 10 + '0'); 37 } 38 39 const int T = 100; 40 int n; 41 db a; 42 ll m[maxn], sum[maxn]; 43 44 int main() 45 { 46 n = read(); scanf("%lf", &a); 47 for(int i = 1; i <= n; ++i) {m[i] = read(); sum[i] = sum[i - 1] + m[i];} 48 for(int i = 1; i <= n; ++i) 49 { 50 int x = i * a; 51 db ans = 0; 52 int L = 1, R = T; 53 while(R <= x) //在一块 54 { 55 ans += (sum[R] - sum[L - 1]) * m[i] / (i - ((L + R) >> 1)); 56 L += T; R += T; 57 } 58 for(int j = L; j <= x; ++j) ans += m[j] * m[i] / (i - j); //块外暴力统计 59 printf("%.6lf ", ans); 60 } 61 return 0; 62 }