http://codeforces.com/contest/629/problem/D
题意:将第i个蛋糕放在第j个蛋糕上(i>j && v[i]>v[j]),求最大的体积是多少
思路:树状数组查询第i个蛋糕前的最大体积,需要离散化
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> using namespace std; #define N 110000 #define met(a, b) memset(a, b, sizeof(a)) const double PI = acos(-1.0); typedef long long LL; int n; LL p[N], Q[N], tree[N]; int lowbit (int t) { return t&(-t); } void Update (int pos, LL x) { while (pos <= n) { tree[pos] = max (tree[pos], x); pos += lowbit(pos); } } LL Query (int pos) { LL ans = 0; while (pos > 0) { ans = max (tree[pos], ans); pos -= lowbit (pos); } return ans; } int main () { while (scanf ("%d", &n) != EOF) { met (p, 0); met (Q, 0); met (tree, 0); for (int i=1; i<=n; i++) { double r, h; scanf ("%lf%lf", &r, &h); p[i] = Q[i] = r*r*h; } sort (Q+1, Q+n+1); int m = unique (Q+1, Q+n+1) - Q;///离散化 LL maxn = 0, res = 0; for (int i=1; i<=n; i++) { int pos = lower_bound (Q+1, Q+m+1, p[i]) - Q;///在Q数组中找到小于p[i]的最大值的位置 res = Query (pos-1) + p[i];///查询i前边的最大体积 maxn = max (maxn, res);///更新总体积 Update (pos, res); } printf ("%.9f\n", (double)maxn*PI); } return 0; }