codeforces 668C - Little Artem and Random Variable

题目链接:http://codeforces.com/contest/668/problem/C

-------------------------------------------------------------------------------------------

大概看一下发现题目给了一些条件限制 然后要解一个方程组

不过数据范围很大 如果直接去解的话显然很困难

考虑到此题是建立在概率的模型上的 因此我们可以用前缀和的方式先把输入处理一下

 

然后就转化为以下子问题

$0 <= x_1, y_1, x_2, y_2 <= 1$

$x_1 * y_1 = a$

$x_2 * y_2 = b$

$x_1 + x_2 = 1$

$y_1 + y_2 = 1$

给定$a\ b$求解$x_1\ x_2\ y_1\ y_2$

 

在草稿纸上画画我们可以发现此处是可以三分的

不过继续观察下我们可以限定所有的$y_i <= x_i$

于是就可以写更为简单的二分了

并且在这个限定条件下 每次求出的解实际上是相互独立的

因此对于每一对解 我们都可以通过二分处理

这样这题就以$O(nlog(10^6))$愉快地解决了

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e5 + 10;
 4 double p1[N], p2[N];
 5 double ans1[N], ans2[N];
 6 int n;
 7 int main()
 8 {
 9     scanf("%d", &n);
10     for(int i = 1; i <= n; ++i)
11         scanf("%lf", &p1[i]);
12     for(int i = 2; i <= n; ++i)
13         p1[i] += p1[i - 1];
14     for(int i = 1; i <= n; ++i)
15         scanf("%lf", &p2[i]);
16     for(int i = n - 1; i; --i)
17         p2[i] += p2[i + 1];
18     for(int i = 1; i < n; ++i)
19     {
20         double L, R, mid;
21         int t = 0;
22         L = max(sqrt(p1[i]), ans1[i - 1]);
23         R = 1;
24         while(++t <= 30)
25         {
26             mid = (L + R) / 2;
27             if((1 - mid) * (1 - p1[i] / mid) <= p2[i + 1])
28                 R = mid;
29             else
30                 L = mid;
31         }
32         ans1[i] = R;
33         ans2[i] = p1[i] / R;
34     }
35     ans1[n] = ans2[n] = 1;
36     for(int i = n; i > 1; --i)
37     {
38         ans1[i] -= ans1[i - 1];
39         ans2[i] -= ans2[i - 1];
40     }
41     for(int i = 1; i <= n; ++i)
42         printf("%.8f%c", ans1[i], i != n ? ' ' : '\n');
43     for(int i = 1; i <= n; ++i)
44         printf("%.8f%c", ans2[i], i != n ? ' ' : '\n');
45     return 0;
46 }

 

posted @ 2016-04-26 18:16 sagitta 阅读(...) 评论(...) 编辑 收藏