CF573E

题意概要

给出一个长度为\(n\)的数列,从中选出一个子序列\(b[1...m]\)(可以为空

使得$$ \sum_{i=1}^m{b_i*i}$$最大,输出这个最大值。

其中\(n\le10^5\)

题解

设\(dp_{i,j}\)表示前\(i\)个数选择\(j\)个数的最大值

那么,转移方程则为:

\[dp_{i,j}=max(dp_{i-1,j},dp_{i-1,j-1}+j*a_i)
\]

于是我们就得到了一个\(n^2\)的做法

我们考虑优化这个式子。

经\(dalao\)证明,发现总有存在一个分界线,这之前的取前者,这之后的取后者

大佬的证明在这里

我们二分分界线,然后用平衡树维护就好了

顺带一提,我今日方知\(splay\)没事多$ splay $几下还会变快

代码

#include<bits/stdc++.h>
#include<windows.h>
#define lch c[x][0]
#define rch c[x][1]
using namespace std;
typedef long long ll;
const int sz=1e5+7;
int n;
ll v,ans;
int rt,cnt;
int f[sz];
int c[sz][2];
int siz[sz];
ll val[sz],tag1[sz],tag2[sz];
inline int newnode(ll v){
int x=++cnt;
val[x]=v;
siz[x]=1;
return x;
}
inline void pushup(int x){
siz[x]=siz[lch]+siz[rch]+1;
}
inline void add(int x,ll tg1,ll tg2){
val[x]+=siz[lch]*tg1+tg2;
tag1[x]+=tg1;
tag2[x]+=tg2;
}
inline void pd(int x){
if(tag1[x]==0&&tag2[x]==0) return;
if(lch) add(lch,tag1[x],tag2[x]);
if(rch) add(rch,tag1[x],tag2[x]+(siz[lch]+1)*tag1[x]);
tag1[x]=0;
tag2[x]=0;
}
inline void pushdn(int x){
if(f[x]) pushdn(f[x]);
pd(x);
}
inline int get(int x){
return c[f[x]][1]==x;
}
inline void dfs(int x){
ans=max(ans,val[x]);
pd(x);
if(lch) dfs(lch);
if(rch) dfs(rch);
}
inline void rotate(int x){
int y=f[x],z=f[y],k=get(x),w=c[x][!k];
if(z) c[z][get(y)]=x;c[x][!k]=y;c[y][k]=w;
if(w) f[w]=y;if(y) f[y]=x;f[x]=z;
pushup(y);
}
inline void splay(int x,int t){
pushdn(x);
while(f[x]!=t){
int y=f[x];
if(f[y]!=t) rotate(get(x)^get(y)?x:y);
rotate(x);
}
pushup(x);
if(t==0) rt=x;
}
inline int find(int k){
int x=rt;
while(1){
pd(x);
if(siz[lch]+1==k) return x;
if(k<=siz[lch]) x=lch;
else k-=siz[lch]+1,x=rch;
}
}
inline void insert(int k,ll v){
int x=find(k-1);splay(x,0);
int y=find(k);splay(y,x);
c[y][0]=newnode(v);
f[c[y][0]]=y;
pushup(y);
pushup(x);
}
inline void modify(int l,int r,ll a,ll b){
int x=find(l-1);splay(x,0);
int y=find(r+1);splay(y,x);
add(c[y][0],a,b);
pushup(y);
pushup(x);
}
int main(){
scanf("%d",&n);
rt=newnode(0);
c[rt][0]=newnode(INT_MIN);
c[rt][1]=newnode(INT_MIN);
f[c[rt][0]]=f[c[rt][1]]=rt;
pushup(rt);
for(int i=1;i<=n;i++){
scanf("%lld",&v);
int l=2,r=i+1;
while(l<r){
int mid=(l+r)>>1;
if(val[find(mid)]+(mid-1)*v>=val[find(mid+1)]) r=mid;
else l=mid+1;
splay(find(mid),0);
}
int x=find(l);
ll y=val[x];
modify(l,i+1,v,v*(l-1));
insert(l,y);
}
dfs(rt);
printf("%lld\n",ans);
}

CF573E (平衡树)的更多相关文章

  1. [BZOJ3223]Tyvj 1729 文艺平衡树

    [BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...

  2. [BZOJ3224]Tyvj 1728 普通平衡树

    [BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...

  3. BZOJ3223: Tyvj 1729 文艺平衡树 [splay]

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Sta ...

  4. [普通平衡树treap]【学习笔记】

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Sta ...

  5. BZOJ 3224: Tyvj 1728 普通平衡树

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9629  Solved: 4091[Submit][Sta ...

  6. BZOJ 3223: Tyvj 1729 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3628  Solved: 2052[Submit][Sta ...

  7. 【Splay】bzoj3223-Tyvj1729文艺平衡树

    一.题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 ...

  8. hiho #1329 : 平衡树·Splay

    #1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...

  9. bzoj 3196: Tyvj 1730 二逼平衡树

    #include<cstdio> #include<ctime> #include<cstdlib> #include<iostream> #defin ...

随机推荐

  1. 聊聊MVC和模块化以及MVVM和组件化

    原文链接 小寒的博客,带你理解更深的世界 面向对象,模块化和MVC 面向对象是指把写程序映射到现实生活,从而一来逻辑性更强,更容易写好代码,二来代码很贴切,通俗易懂,更被人理解,三来更加容易拓展和管理 ...

  2. idea怎么打war包

    1.上方导航栏粥找到 Buid——> Bild Artifacts... 2.弹出框中选择 3.war包打好啦,一般放在编译的 target目录下

  3. GitHub:如何构建一个股票市场知识图谱?(附代码&链接)

    来源:专知 本文约 600007 董事⻓/董事 高燕 女 60 600007 执⾏董事 刘永政 男 50 600008 董事⻓/董事 ··· ··· ··· ··· ··· 注:建议表头最好用相应的英 ...

  4. Activiti配置实例以及Spring集成配置

    public class TestDB { public static void main(String[] args) { //1. 创建Activiti配置对象的实例 ProcessEngineC ...

  5. 跟我一起学习webpack输出动态HTML(三)

    跟着之前的项目来 我们没打包一次就会生成一个bundile.js,我们要更新最新的代码不希望有缓存,那么这个时候我们就是更改资源的URL, 每当代码发生变化时,相应的hash也会发生变化.这个时候我们 ...

  6. 错误 2 error C2059: 语法错误:“::”

    设置项目属性,在预定义处理器中添加定义NOMINMAX来禁止使用Vsual C++的min/max宏定义. 项目属性   ——> C/C++ ——> 预处理器 ——> 预处理器定义 ...

  7. Session - 什么叫一次会话

    转载自:https://blog.csdn.net/qin_xiaofang/article/details/77725946 网上收集的:Session代表服务器与浏览器的一次会话过程,这个过程是连 ...

  8. Java文件写入

    一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所有现有的内容,然而,当指定一个true (布尔)值作为FileWritter构造函 ...

  9. IO流17 --- 对象流操作自定义对象 --- 技术搬运工(尚硅谷)

    序列化 @Test public void test14() throws IOException { ObjectOutputStream oos = new ObjectOutputStream( ...

  10. virtualenv简单使用

    前提 在开发过程中,经常需要使用各种第三方库,而且python又提供了pip,easy_install等工具来简化库的安装,所以很容易就会在系统python的site-packages目录中装满各种各 ...