• 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]);
    }
    
  • 相关阅读:
    使用 Sentry集中处理错误
    laravel实现多对多的分析
    windows下phpstorm的快捷键
    npm 升级
    squid----正向代理
    nginx----配置优化
    负载均衡----nginx
    负载均衡----HAproxy
    负载均衡----LVS
    mysql-8.0.12读写分离
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11761726.html
Copyright © 2020-2023  润新知