• D. Babaei and Birthday Cake---cf629D(LIS线段树优化)


    题目链接:http://codeforces.com/problemset/problem/629/D

    题意就是现有n个蛋糕,蛋糕的形状是圆柱体,每个蛋糕的体积就是圆柱体的体积,每个蛋糕的编号是1---n,可以把蛋糕 i 放到蛋糕 j 上面,前提是 j<i 并且 Vj<Vi;最后求最大的体积是多少;

    实质就是求上升子序列的最大和,但是由于n的范围是10w所以不能用n^2的复杂度,所以可以用线段树进行优化,时间复杂度变为nlogn

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <vector>
    using namespace std;
    typedef long long LL;
    #define PI 4*atan(1.0)
    #define N 302000
    #define met(a, b) memset(a, b, sizeof(a))
    
    #define Lson r<<1
    #define Rson r<<1|1
    
    double v[N], b[N];
    
    struct node
    {
        int L, R;
        double Max;///表示这个区间内的最大值,
        int Mid(){ return (L+R)/2; }
    }a[N*4];
    
    void Build(int r, int L, int R)
    {
        a[r].L = L, a[r].R = R;a[r].Max = 0;
        if(L == R)return;
        Build(Lson, L, a[r].Mid());
        Build(Rson, a[r].Mid()+1, R);
    }
    
    double Query(int r, int L, int R)
    {
        if(L > R) return 0;
    
        if(a[r].L == L && a[r].R == R)
            return a[r].Max;
    
        if(R <= a[r].Mid())
            return Query(Lson, L, R);
        else if(L > a[r].Mid())
            return Query(Rson, L, R);
        else
        {
            double ans1 = Query(Lson, L, a[r].Mid());
            double ans2 = Query(Rson, a[r].Mid()+1, R);
            return max(ans1, ans2);
        }
    }
    
    void Update(int r, int pos, double num)
    {
        if(a[r].L == a[r].R && a[r].L == pos)
        {
            a[r].Max = num;
            return ;
        }
        if(pos <= a[r].Mid())
            Update(Lson, pos, num);
        else
            Update(Rson, pos, num);
    
        a[r].Max = max(a[Lson].Max, a[Rson].Max);
    }
    
    int main()
    {
        int n;
        LL r, h;
        while(scanf("%d", &n)!=EOF)
        {
            for(int i=1; i<=n; i++)
            {
                scanf("%I64d %I64d", &r, &h);
                v[i] = b[i] = PI*h*r*r;
            }
            sort(b, b+n);
            int len = unique(b, b+n) - b;
    
            Build(1, 1, len);
    
            double ans = 0;
            for(int i=1; i<=n; i++)
            {
                int pos = lower_bound(b, b+len, v[i]) - b;///每次找到当前这个数能放的位置;
                double res = Query(1, 1, pos-1) + v[i];///找到这个位置之前的最大值
                Update(1, pos, res);///找到之后把这个值加到那个位置上
                ans = max(ans, res);
            }
            printf("%.12f
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Maven版本管理
    ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口
    java常用集合框架关系
    重写equals和hashCode
    项目的继承和聚合详解
    Installation Manager1.8安装
    关于java按位操作运算
    正数负数的二进制表示
    springboot问题排解
    int和Integer有什么区别
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5480810.html
Copyright © 2020-2023  润新知