codeforces 629D Babaei and Birthday Cake

题目链接:

  codeforces 629D Babaei and Birthday Cake

题目描述:

  有n个圆柱形蛋糕,按照顺序每个蛋糕都有一个编号。当蛋糕i可以摞在蛋糕j上,要满足条件i<j, 并且蛋糕i的体积不小于蛋糕j的体积。问最后组成的蛋糕最大体积为多少?

解题思路:

  以前遇到这样的题目都是dp的,时间复杂度大概O(n*n),但是这个题目数据范围是1e5,普通dp肯定GG。可以用线段树或者set优化一下,我选择用线段树,先把所有蛋糕的体积计出来,然后按照体积升序离散化建立线段树。但是往线段树中加点的时候要按照编号。每次加点只需要查找当前节点之前的最大sum即可。最近突然感觉自己好弱,千年吊车尾,还好状态比较不错......

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define rson(root) 2*root+1
 5 #define lson(root) 2*root
 6 
 7 const int maxn = 100010;
 8 const double PI = acos(-1.0);
 9 struct node
10 {
11     int l, r;
12     double sum;
13 
14     int mid ()
15     {
16         return (l + r) / 2;
17     }
18 }tree[4*maxn];
19 double r[maxn], h[maxn], v[maxn], a[maxn];
20 
21 void build (int root, int l, int r)
22 {
23     int mid = (l + r) / 2;
24     tree[root].l = l;
25     tree[root].r = r;
26     tree[root].sum = 0;
27 
28     if (l == r)
29         return ;
30 
31     build (lson(root), l, mid);
32     build (rson(root), mid+1, r);
33 }
34 
35 double query (int root, int l, int r)
36 {
37     if (tree[root].l == l && tree[root].r == r)
38         return tree[root].sum;
39 
40     if (tree[root].mid() >= r)
41         return query (lson(root), l, r);
42     else if (tree[root].mid() < l)
43         return query (rson(root), l, r);
44     else
45         return max (query(lson(root), l, tree[root].mid()), query (rson(root), tree[root].mid()+1, r));
46 }
47 
48 void updata (int root, int pos, double x)
49 {
50     if (tree[root].l == pos && tree[root].r == pos)
51         {
52             tree[root].sum = x;
53             return ;
54         }
55     if (tree[root].mid() < pos)
56         updata (rson(root), pos, x);
57     else
58         updata (lson(root), pos, x);
59     tree[root].sum = max (tree[lson(root)].sum, tree[rson(root)].sum);
60 }
61 
62 int main ()
63 {
64     int n;
65     while (scanf("%d", &n) != EOF)
66     {
67         for (int i=0; i<n; i++)
68         {
69             scanf ("%lf %lf", &r[i], &h[i]);
70             a[i] = v[i] = r[i] * r[i] * h[i];
71         }
72 
73         sort (a, a+n);
74         build (1, 0, n);
75 
76         for (int i=0; i<n; i++)
77         {
78             int pos = lower_bound (a, a+n, v[i]) - a;
79             double x;
80 
81             if (pos == 0)
82                 x = v[i];
83             else
84                 x = query (1, 0, pos-1) + v[i];
85 
86             updata (1, pos, x);
87         }
88 
89         printf ("%.12lf\n", query (1, 0, n)*PI);
90     }
91     return 0;
92 }

 

posted @ 2016-05-11 11:20  罗茜  阅读(372)  评论(0编辑  收藏  举报