正题

题目链接:https://www.luogu.com.cn/problem/CF573E


题目大意

给出一个长度为nnn的序列aaa,求它的一个子序列bbb,要求最大化
∑i=1∣b∣bi×i\sum_{i=1}^{|b|}b_i\times ii=1∑∣b∣​bi​×i

1≤n≤105,∣ai∣≤1071\leq n\leq 10^5,|a_i|\leq 10^71≤n≤105,∣ai​∣≤107


解题思路

首先我们考虑最暴力的dpdpdp,设fi,jf_{i,j}fi,j​表示到现在到aaa的第iii个,然后选择了jjj个时的最大答案,那么我们有
fi,j=max{fi−1,j,fi−1,j−1+bi×j}f_{i,j}=max\{f_{i-1,j},f_{i-1,j-1}+b_i\times j\}fi,j​=max{fi−1,j​,fi−1,j−1​+bi​×j}
然后发现这个dpdpdp很难进行维护,我们尝试找下性质。
然后我没找到去看题解发现确实是性质题,对于一个iii,如果fi,jf_{i,j}fi,j​从fi,j−1f_{i,j-1}fi,j−1​转移过来,那么fi,j+1f_{i,j+1}fi,j+1​也一定是从fi−1,jf_{i-1,j}fi−1,j​转移过来的。

证明的话可以看这篇大佬的博客:https://www.luogu.com.cn/blog/Mrsrz/solution-cf573e

所以我们可以用一个平衡树去维护每个iii的dpdpdp值,然后我们就只需要二分出两个转移方式的中转点kkk,然后对于前面的我们不变,对于后面的我们在区间前插入一个fi,k−1f_{i,k-1}fi,k−1​,然后就是一个区间加等差序列的操作,用懒标记维护即可。

时间复杂度:O(nlog⁡2n)O(n\log^2 n)O(nlog2n)

如果在平衡树上二分能做到O(nlog⁡n)O(n\log n)O(nlogn)

当然还有另一种做法,考虑一个一个插入答案,能够证明不停插入会使得当前贡献最大的数也是最优的。

那么我们就只需要用分块维护每一个数的新贡献就好了。

时间复杂度:O(nn)O(n\sqrt n)O(nn​)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const ll N=1e5+10;
ll n,cnt,rt,t[N][2],dat[N],siz[N];
ll w[N],lazy[N],lazy2[N],ans;
ll Newp(ll val){w[++cnt]=val;dat[cnt]=rand();siz[cnt]=1;return cnt;
}
ll Cpy(ll x)
{return Newp(w[x]);}
void Update(ll x,ll val,ll dr){w[x]+=val*(siz[t[x][0]]+dr);lazy[x]+=val*dr;lazy2[x]+=val;
}
void PushDown(ll x){if(lazy[x]){if(t[x][0])w[t[x][0]]+=lazy[x],lazy[t[x][0]]+=lazy[x];if(t[x][1])w[t[x][1]]+=lazy[x],lazy[t[x][1]]+=lazy[x];lazy[x]=0;}if(lazy2[x]){if(t[x][0])Update(t[x][0],lazy2[x],0);if(t[x][1])Update(t[x][1],lazy2[x],siz[t[x][0]]+1);lazy2[x]=0;}return;
}
void PushUp(ll x){siz[x]=siz[t[x][0]]+siz[t[x][1]]+1;return;}
void Split(ll &x,ll &y,ll p,ll val){if(!p){x=y=0;return;}PushDown(p);if(siz[t[p][0]]<=val)x=p,Split(t[x][1],y,t[p][1],val-siz[t[p][0]]-1);else y=p,Split(x,t[y][0],t[p][0],val);PushUp(p);
}
ll Merge(ll x,ll y){if(!x||!y)return x|y;PushDown(x);PushDown(y);if(dat[x]<dat[y]){t[x][1]=Merge(t[x][1],y);PushUp(x);return x;}else{t[y][0]=Merge(x,t[y][0]);PushUp(y);return y;}
}
ll GetVal(ll &rt,ll pos){ll x,y,z;Split(x,z,rt,pos);Split(x,y,x,pos-1);ll ans=w[y];x=Merge(x,y);rt=Merge(x,z);return ans;
}
void GetAns(ll x){if(!x)return;PushDown(x);ans=max(ans,w[x]);GetAns(t[x][0]);GetAns(t[x][1]);return;
}
bool check(ll x,ll w){ll a=GetVal(rt,x);ll b=GetVal(rt,x-1);return a>b+x*w;
}
signed main()
{scanf("%lld",&n);rt=Newp(0);rt=Merge(rt,Newp(-1e18));for(ll i=1,k;i<=n;i++){scanf("%lld",&k);ll l=1,r=i;while(l<=r){ll mid=(l+r)>>1;if(check(mid,k))l=mid+1;else r=mid-1;}ll x,y,z,d;Split(x,z,rt,l-1);Split(z,d,z,n-1);Split(x,y,x,l-2);d=Cpy(y);z=Merge(d,z);Update(z,k,l);rt=x;rt=Merge(rt,y);rt=Merge(rt,z);}GetAns(rt);printf("%lld\n",ans);return 0;
}```

CF573E-Bear and Bowling【dp,平衡树】相关推荐

  1. 【分治+斜率优化】BZOJ2149拆迁队 CF660F Bear and Bowling 4

    BZOJ2149拆迁队 [题目] 原题地址 题目大意不想写. [题目分析] 斜率优化的dp是显然的,然后就是怎么维护的问题了. [解题思路] 这题显然就是一个斜率优化的dp,然后分治的时候维护一下凸壳 ...

  2. 2016区域赛前冲刺训练

    UPD 2016.10.23 shift-and (2题) Codeforces 训练 现在已经完成了: 191 [Codeforces Round #377] (6/6) Div 2 A Buy a ...

  3. OI每周刷题记录——lrllrl

    看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...

  4. P4309 [TJOI2013]最长上升子序列 平衡树 + dp

    传送门 文章目录 题意: 思路: 题意: 思路: 注意到一个很关键的条件,每次插入iii,而iii是递增的,也就是说插入iii之后只会从前面的最大值转移过来,所以我们现在只需要维护插入操作即可,这个显 ...

  5. 【CodeForces - 574D】Bear and Blocks (dp,思维)

    题干: Limak is a little bear who loves to play. Today he is playing by destroying block towers. He bui ...

  6. jzoj5990. 【北大2019冬令营模拟2019.1.6】Bear (状压dp)

    题面 题解 我永远讨厌dp.jpg 搞了一个下午优化复杂度最后发现只要有一个小trick就可以A了→_→.全场都插头dp就我一个状压跑得贼慢-- 不难发现我们可以状压,对于每一行,用状态\(S\)表示 ...

  7. CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)

    题目链接:点击查看 题目大意:给出一个 01 字符串,规定求值的过程如下: 每次选择末尾的两个数字: 如果为 0 0 ,那么替换成一个 1 否则替换成一个 0 循环往复,直至只剩一个数字位置,剩下的数 ...

  8. [2021-09-02 contest]CF1251C,可达性统计(bitset优化dp),Boomerang Tournament(状压dp),小蓝的好友(mrx)(treap平衡树)

    文章目录 CF1251C Minimize The Integer acwing164:可达性统计 Facebook Hacker Cup 2016 Round 1 Boomerang Tournam ...

  9. CodeForces 771C Bear and Tree Jumps 树形DP

    题意: 给出一棵树,一个人可以在树上跳,每次最多跳\(k(1 \leq k \leq 5)\)个点 定义\(f(s,t)\)为从顶点\(s\)跳到顶点\(t\)最少需要跳多少次 求\(\sum\lim ...

最新文章

  1. 卷积神经网络--CNN
  2. Data-truncation--Incorrect-string-value
  3. zabbix如何监控WEB应用性能
  4. 重置样式表--HTML
  5. 项望烽:移动IM开发那些事儿
  6. ds18b20温度转换指令_【Proteus】DS18B20简易温控器
  7. abp执行mysql语句_在ABP模板工程中使用MySql
  8. 七年也扶不起的苹果 Siri
  9. 三十天学不会TCP,UDP/IP网络编程-IP头格式祥述
  10. 【译】BMP格式与JPG格式之间的区别
  11. 【C语言】C语言小项目—贪吃蛇
  12. 计算机桌面怎么分区域,怎样设置电脑桌面的区域分割?
  13. 完美解决Tensorflow不支持AVX2指令集问题
  14. java日记 简单Java家庭记账系统
  15. 华为交换机 查ip冲突_华为交换机发现邻居操作,查看端口和ip
  16. 什么叫做会议中控及其实际应用
  17. 小程序 侧边栏(导航)滑动
  18. 一个矩阵与单位矩阵相乘等于本身吗?并且符合交换律吗?
  19. 刘世光 计算机图像学,刘世光
  20. 打造高效的项目团队,促进项目进度管理

热门文章

  1. 计算机广告制作未来发展还行吗,计算机多媒体设计专业和广告设计制作那个好...
  2. 服务器的类型及作用是什么,按用途分类,服务器有哪些? - 问答库
  3. oracle unpivot 空值,sql – 处理UNPIVOT中的NULL值
  4. android studio 创建.9文件,自己使用Android studio创建.9(点9)图片
  5. android studio插入数据表中没有_学Java能拿高薪吗 Java中常见排序算法有哪些
  6. java 最好 入门_C++和Java哪个比较好入门?初学者该如何选择?
  7. 计算机应用乘法,计算机系统原理(十) 二进制整数的乘法运算和除法运算
  8. rsa 模数 指数转换 c语言_模数转换,你必须知道的8个经典ADC转换电路方案
  9. html中label的寬度無法修改,如何设置HTML span、label 的宽度
  10. 两台思科交换机vlan划分_Cisco交换机Vlan划分及ACL配置详细步骤 | 吴文辉博客