Codeforces 629D Babaei and Birthday Cake 树状数组,LIS

这个题有点像lis,但是又不是常规的lis,因为它不是要求子序列最长,而是要求子序列的权值最大,所以用树状数组来维护这个最大值,tree[i]表示当第i个simple cake在最上层时,cake的体积最大是多少。那么本题的做法就是先算出每个simple cake的体积,然后给它们排序,然后遍历原始顺序的simple cake,设为i,找到i在排好序的数组中的位置pos,找到[1,pos-1]区间内树的最大值,把i插进去,更新树状数组。

#include <cstdio>
#include <cstdlib>
#include <stack>
#include <map>
#include <cmath>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
const double pi = acos(-1.0);
LL v1[100005], v2[100005], tree[1000005];
int n;

int lowbit(int x)
{
	return x&-x;
}

LL query(int pos)
{
	LL ans = 0;
	while(pos > 0)
	{
		ans = max(ans, tree[pos]);
		pos -= lowbit(pos);
	}
	return ans;
}

void update(int pos, LL key)
{
	while(pos <= n)
	{
		tree[pos] = max(tree[pos], key);
		pos += lowbit(pos);
	}
}

int main()
{
	//freopen("ztest.txt","r",stdin);
	scanf("%d", &n);
	LL r, h;
	for(int i = 1; i <= n; i++)
	{
		scanf("%lld%lld",&r, &h);
		v1[i] = v2[i] = r*r*h;
	}
	sort(v1+1, v1+n+1);
	int tot = unique(v1+1, v1+n+1)-v1;
	LL ans = 0;
	for(int i = 1; i <= n; i++)
	{
		int pos = lower_bound(v1+1, v1+tot+1, v2[i])-v1;
		LL temp = query(pos-1)+v2[i]; 
		ans = max(ans, temp);
		update(pos, temp);
	}
	printf("%.9lf\n",(double)ans*pi);
	return 0;
}
		 

猜你喜欢

转载自blog.csdn.net/WukongAKK/article/details/81252363