zoukankan      html  css  js  c++  java
  • Luogu P5504 [JSOI2011]柠檬

    题目
    首先我们容易想到,每一个连续段两端的颜色一定相同。
    预处理出(sum_i)表示(1sim i)中颜色为(a_i)的贝壳的个数。
    (f_i)为前(i)个贝壳的最大答案。
    那么容易写出转移方程(f_i=maxlimits_{jin[1,i]wedge a_i=a_j}(f_{j-1}+a_i(sum_i-sum_j+1)^2))
    这个东西显然可以斜率优化,每种颜色维护一个凸包即可。
    可以拆成这样
    (f_i=a_i(sum_i+1)^2+maxlimits_{jin[1,i]wedge a_i=a_j}((-2sum_i)(a_jsum_j)+(f_{j-1}+a_jsum_j^2-2a_jsum_j)))

    #include<bits/stdc++.h>
    #define ll long long
    #define ld long double
    #define pub push_back
    #define pob pop_back
    #define t1 s[id][s[id].size()-1]
    #define t2 s[id][s[id].size()-2]
    using namespace std;
    const int N=100007,M=10007;const ld eps=1e-8;
    int a[N],sum[N],pos[N];vector<int>s[N];ll x[N],y[N],f[N];
    int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
    ld slope(int i,int j){return (ld)(y[j]-y[i])/(x[j]-x[i]);}
    ll sqr(int x){return 1ll*x*x;}
    int main()
    {
        int n=read(),i,id;
        for(i=1;i<=n;++i) a[i]=read(),sum[i]=sum[pos[a[i]]]+1,pos[a[i]]=i;
        for(i=1;i<=n;++i) x[i]=1ll*sum[i]*a[i];
        for(i=1;i<=n;++i)
        {
    	id=a[i],y[i]=f[i-1]+1ll*a[i]*sum[i]*(sum[i]-2);
    	while(s[id].size()>=2&&slope(t2,t1)<=slope(t2,i)+eps) s[id].pob();
    	s[id].pub(i);
    	while(s[id].size()>=2&&slope(t2,t1)<=2.0*sum[i]+eps) s[id].pob();
    	f[i]=f[t1-1]+a[i]*sqr(sum[i]-sum[t1]+1);
        }
        return !printf("%lld",f[n]);
    }
    
  • 相关阅读:
    java jdk 安装后目录下没有 jre
    解决leader-line生成的svg线不能被html2canvas转成图片问题
    css 计数实现目录索引
    前端架构入门
    js 尺寸信息
    阿里云25端口被封,换465端口发送
    appache官网下载 httpClient
    oc基础:类的定义
    指针的地址(地址的地址)
    0 ‘与‘’、 ‘0’
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11761726.html
Copyright © 2011-2022 走看看