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

BZOJ3316 JC loves Mkk

时间:2015-02-15 23:04:38      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

首先断环成链,变成两倍长度。

然后二(fen)分(shu)答(gui)案(hua),查看答案为ans的长度在[L, R]之间的链存不存在。

我们可以维护前缀和,用单调队列O(n)判断是否和大于0

又学习了个黑科技。。。::x表示全局变量x。。。

 

技术分享
 1 /**************************************************************
 2     Problem: 3316
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:1960 ms
 7     Memory:5492 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cmath>
12 #include <algorithm>
13  
14 using namespace std;
15 typedef long double llf;
16 typedef long long ll;
17 const int N = 200005;
18 const llf eps = 1e-10;
19  
20 int n, L, R, mx, a[N];
21 llf sum[N];
22 ll ans1, ans2, gcd;
23 int q[2][N], h[2], t[2];
24  
25 inline int read() {
26   int x = 0;
27   char ch = getchar();
28   while (ch < 0 || 9 < ch)
29     ch = getchar();
30   while (0 <= ch && ch <= 9) {
31     x = x * 10 + ch - 0;
32     ch = getchar();
33   }
34   return x;
35 }
36  
37 bool check(llf x) {
38   int i;
39   for (i = 1; i <= n; ++i)
40     sum[i] = sum[i - 1] + a[i] - x;
41   h[0] = h[1] = t[0] = t[1] = 0;
42   for (i = L; i <= n; ++i) {
43     int *q = ::q[i & 1], &h = ::h[i & 1], &t = ::t[i & 1], now = i - L;
44     while (h < t && sum[q[t]] > sum[now]) --t;
45     q[++t] = now;
46     while (i - q[h + 1] > R) ++h;
47     if (sum[i] - sum[q[h + 1]] >= 0) {
48       ans2 = i - q[h + 1];
49       return 1;
50     }
51   }
52   return 0;
53 }
54  
55 llf work() {
56   llf l = 0, r = mx, mid;
57   while (r - l > eps) {
58     mid = (l + r) / 2.0;
59     if (check(mid)) l = mid;
60     else r = mid;
61   }
62   return (l + r) / 2.0;
63 }
64  
65 int main() {
66   int i;
67   n = read(), L = read(), R = read();
68   if (L & 1) ++L;
69   if (R & 1) --R;
70   for (i = 1; i <= n; ++i) {
71     a[i] = a[n + i] = read();
72     mx = max(mx, a[i]);
73   }
74   n <<= 1;
75    
76   ans1 = (ll) (work() * ans2 + 0.5);
77   gcd = __gcd(ans1, ans2);
78   ans1 /= gcd, ans2 /= gcd;
79   if (ans2 == 1) printf("%lld\n", ans1);
80   else printf("%lld/%lld\n", ans1, ans2);
81   return 0;
82 }
View Code

 

BZOJ3316 JC loves Mkk

标签:

原文地址:http://www.cnblogs.com/rausen/p/4293505.html

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