bzoj4709 [jsoi2011]柠檬

Description

Flute 很喜欢柠檬。它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬。贝壳一共有 N (1 ≤ N

≤ 100,000) 只,按顺序串在树枝上。为了方便,我们从左到右给贝壳编号 1..N。每只贝壳的大小不一定相同,

贝壳 i 的大小为 si(1 ≤ si ≤10,000)。变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,并

选择一种贝壳的大小 s0。如果 这一小段贝壳中 大小为 s0 的贝壳有 t 只,那么魔法可以把这一小段贝壳变成 s

0t2 只柠檬。Flute 可以取任意多次贝壳,直到树枝上的贝壳被全部取完。各个小段中,Flute 选择的贝壳大小 s

0 可以不同。而最终 Flute 得到的柠檬数,就是所有小段柠檬数的总和。Flute 想知道,它最多能用这一串贝壳

变出多少柠檬。请你帮忙解决这个问题。

Input

第 1 行:一个整数,表示 N。

第 2 .. N + 1 行:每行一个整数,第 i + 1 行表示 si。

Output

仅一个整数,表示 Flute 最多能得到的柠檬数。

对位置i,f[i]表示考虑前i个元素的最多柠檬数

f[0]=1

f[i]=max f[j-1]+a[i]*(j到i之间si出现次数)^2 , 1<=j<=i,si=sj

对每个si分别用单调栈维护斜率优化dp,决策不单调但可以三分求出决策点

#include<cstdio>
#include<vector>
typedef long long i64;
const int R=5000000,N=100007;
char buf[R+3],*ptr=buf-1;
int _(){
    int x=0,c=*++ptr;
    while(c<48)c=*++ptr;
    while(c>47)x=x*10+c-48,c=*++ptr;
    return x;
}
int n,a[N],pv[N],pw[10007],c[N];
i64 f[N];
std::vector<int>q[10007];
void maxs(i64&a,i64 b){if(a<b)a=b;}
i64 p2(i64 x){return x*x;}
double F(int x,int y,int ci,int ai){
    return (f[x-1]-f[y-1]+ai*(p2(c[x])-p2(c[y])))/double(i64(c[x]-c[y])*ai<<1);
}
int main(){
    fread(buf,1,R,stdin);
    n=_();
    for(int i=1;i<=n;++i){
        pv[i]=pw[a[i]=_()];
        c[i]=c[pw[a[i]]]+1;
        pw[a[i]]=i;
    }
    for(int i=1;i<=n;++i){
        int w=a[i],ci=c[i]+1;
        std::vector<int>&Q=q[w];
        while(Q.size()>1&&F(i,Q[Q.size()-1],ci,w)>F(Q[Q.size()-1],Q[Q.size()-2],ci,w))Q.pop_back();
        Q.push_back(i);
        int l=0,r=Q.size()-1;
        while(l+4<=r){
            int m1=l+r>>1,m2=m1+r>>1;
            if(f[Q[m1]-1]+w*p2(ci-c[Q[m1]])<f[Q[m2]-1]+w*p2(ci-c[Q[m2]]))l=m1;
            else r=m2;
        }
        for(int p=l;p<=r;++p)maxs(f[i],f[Q[p]-1]+w*p2(ci-c[Q[p]]));
    }
    printf("%lld",f[n]);
    return 0;
}
时间: 2024-11-07 13:32:52

bzoj4709 [jsoi2011]柠檬的相关文章

[BZOJ4709][JSOI2011]柠檬 决策单调性优化dp

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4709 我好弱啊QAQ,网上dalao们的题解根本看不懂啊,折腾了几个小时,有一点明白了. 首先要把朴素dp方程退出来. ①题目中说每次从序列的左右选一端取,但是如果你真的照着题目说的这样做我也不知道会怎么样.事实上很明显不管怎么取,最终答案都只跟划分出的是哪几个区间有关.所以不妨从左端开始取. ②如果取一个区间,区间第一个贝壳的大小和最后一个贝壳的大小不一样,那么很明显可以去掉第一个或最

bzoj 4709: [Jsoi2011]柠檬

Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从左到右给贝壳编号 1..N.每只贝壳的大小不一定相同, 贝壳 i 的大小为 si(1 ≤ si ≤10,000).变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,并 选择一种贝壳的大小 s0.如果 这一小段贝壳中 大小为 s0 的贝壳有 t 只,那么魔法可以把这一小段贝壳变成 s

luogu P5504 [JSOI2011]柠檬

luogu 首先是那个区间的价值比较奇怪,如果推导后可以发现只有左右端点元素都是同一种\(s_x\)的区间才有可能贡献答案,并且价值为\(s_x(cnt(x)_r-cnt(x)_{l-1})^2\),这是因为如果选出来的这种元素的端点的左右两边还有其他元素,那么显然的把那些其他的元素另外划分在别的区间里可以获得更优的答案 然后现在就可以\(O(n^2)\)了,转移大概为\(f_i=\min_{j<i,s_j=s_i} f_{j-1}+s_i(cnt(s_i)_i-cnt(s_i)_{j-1})^

[JSOI2011]柠檬

推(chao)式子: 令$f_i$表示以i结尾时取得的最大值,$c_i$表示$a_i$这个数在第i个位置是第$c_i$次出现,则有: $$f_i=f_{j-1}+(c_i-c_j+1)^2*a_i$$ 不妨设j>k时从j转移比从i转移更优 则有: $$f_{j-1}+(c_i-c_j+1)^2·a_i>f_{k-1}+(c_i-c_k+1)^2·a_i$$ 其中$a_i$是常数,我们考虑最后再乘回去,所以先不管它 然后化简有: $$(f_{j-1}+(c_j-1)^2)-(f_{k-1}+(c

YCB 的暑期计划

前言 YCB现在很弱(TAT) 暑假有一个月,赶快狂补一下. 大概的计划如下: 首先前期会以数据结构为主,毕竟代码能力太弱,涉及内容:线段树分治.二进制分组.KD-Tree. 等数据结构做到没有智商的时候加入一波数论,内容为 杜教筛.min_25筛. 然后中途小清新一下,做一些 组合博弈与构造题. 接着继续练代码能力,顺便学一些神奇的暴力:启发式合并.dsu on tree . 然后图论也忘的差不多了,就回过头去学点新东西,大概会有spfa判负环.0/1分数规划.差分约束. 估计这个时候也没有什

[BZOJ4907]柠檬

4709: [Jsoi2011]柠檬 Time Limit: 10 Sec  Memory Limit: 128 MB Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从左到右给贝壳编号 1..N.每只贝壳的大小不一定相同, 贝壳 i 的大小为 si(1 ≤ si ≤10,000).变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,

[洛谷U22158]策划体验(树上斜率优化)(二分最优决策)

题目背景 OL不在,Clao又在肝少*前线,他虽然觉得这个游戏的地图很烦,但是他认为地图的难度还是太低了,习习中作为策划还不够FM,于是他自己YY了一种新的地图和新的机制: 题目描述 整个地图呈树形结构,共有N+1 个节点,0 号节点为树的根节点,并且,与0 号节点相连的就只有1 号节点,除0 号节点外的所有节点上都会有一队战斗力为V_i的敌人存在: 指挥部设在0 号节点,玩家的操纵梯队只能出生在该节点,并且在进入地图时玩家将选择任意一个节点作为本次任务的终点,设为E ,玩家只需要将根节点到EE

[bzoj4709][柠檬]

bzoj4709 思路 首先,最优秀的分法一定是每段两端都是这一段中最多的那个,否则可以把不是的那个踢出去单独成段肯定会更优秀.然后就成了将这个序列分段,保证每段两端元素相同的最大收益和. 用a[i]记录第i个位置上的数,用s[i]记录前i个元素中a[i]出现的次数.f[i]表示以前i个数的最大收益. 首先考虑\(n^2\)的dp.明显\(f[i]=max\{f[j]+a[i]*(s[i]-s[j]+1)^2\} (a[i]==a[j])\) for(int i=1;i<=n;++i) for(

「JSOI2011」柠檬

传送门 Luogu 解题思路 还是一道斜率优化题. 在优化前,还有一个值得一提的优化: 对于最后的最有分割方案,每一段的两个端点一定是同颜色的,并且作为这一段的 \(s_0\) 证明:如果不作为这一段的 \(s_0\),那么它显然没有贡献,把这一个单独分出来显然更优,直到最后两个端点就一定都是 \(s_0\) ,颜色相同. 那么我们只需要从之前和该点种类相同的位置进行转移即可. 这样就从直接枚举的复杂度 \(O(n^3)\) 优化到了 \(O(n^2)\) ,但还是不够,继续考虑优化. 我们先把