CodeForces 629D Babaei and Birthday Cake(树状数组+离散化)

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;
}


你可能感兴趣的:(CodeForces 629D Babaei and Birthday Cake(树状数组+离散化))