正题

题目链接:http://noi.ac/problem/2139


题目大意

给出\(n\)个数字的序列\(a_i\)。然后选出一个不降子序列最大化子序列的\(a_i\)和减去没有任何一个数被选中的区间数量。

\(1\leq n\leq 10^6,1\leq a_i\leq 10^8\)


解题思路

嗯,考虑朴素的\(dp\)方程,设\(f_i\)表示以\(i\)为末尾的值就有

\[f_i=f_j+a_i+\frac{(i-j-1)(i-j)}{2}
\]

然后展开整理一下都乘二就是

\[f_i=f_j+2a_i+i^2-i+j^2+j-2ij(a_j\leq a_i,j<i)
\]

除了\(a_j\leq a_i\)就是一个标准的斜率优化式子了

然后这个东西其实挺好搞的,因为多一个限制直接上\(CDQ\)就好了,但是每次左边要归并排序,这样时间复杂度就是\(O(n\log n)\)的了

但其实还有更暴力的做法,因为既然一个\(CDQ\)能做到,那么找些数据结构之类的也肯定能做到。

对于树状数组上每个节点维护一个凸壳然后暴力查询就好了

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
#define lowbit(x) (x&-x)
using namespace std;
const ll N=1e6+10;
ll n,m,a[N],b[N],l[N],r[N],f[N],k[N];
vector<ll >q[N];
ll calc(ll i,ll j)
{return k[i]+2*i*j;}
void Change(ll x,ll i){
while(x<=m){
while(l[x]<r[x]&&(k[i]-k[q[x][r[x]]])*(q[x][r[x]]-q[x][r[x]-1])>=(k[q[x][r[x]]]-k[q[x][r[x]-1]])*(i-q[x][r[x]]))
r[x]--,q[x].pop_back();
q[x].push_back(i);r[x]++;x+=lowbit(x);
}
return;
}
ll Ask(ll x,ll i){
ll ans=-1e18;
while(x){
while(l[x]<r[x]&&calc(q[x][l[x]],i)<calc(q[x][l[x]+1],i))
l[x]++;
if(l[x]<=r[x])ans=max(ans,calc(q[x][l[x]],i));
x-=lowbit(x);
}
return ans;
}
signed main()
{
scanf("%lld",&n);
for(ll i=1;i<=n;i++)
scanf("%lld",&a[i]),b[i]=a[i];
sort(b+1,b+1+n);
m=unique(b+1,b+1+n)-b-1;
for(ll i=1;i<=m;i++)r[i]=-1;
Change(1,0);
for(ll i=1;i<=n;i++){
ll x=lower_bound(b+1,b+1+m,a[i])-b;
f[i]=Ask(x,i)+2*a[i]-i*i+i;
k[i]=f[i]-i*i-i;
Change(x,i);
}
ll ans=-1e18;
for(ll i=1;i<=n;i++)
ans=max(ans,f[i]/2-(n-i+1)*(n-i)/2);
printf("%lld\n",ans);
return 0;
}

NOI.AC#2139-选择【斜率优化dp,树状数组】的更多相关文章

  1. 奶牛抗议 DP 树状数组

    奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...

  2. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  3. bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 793  Solved: 503[Submit][S ...

  4. 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...

  5. bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化

    3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 314  Solved: 132[Submit][Sta ...

  6. Codeforces 909 C. Python Indentation (DP+树状数组优化)

    题目链接:Python Indentation 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现.现在有一种简化版的Python,只有两种语句: (1)'s'语句:Simple ...

  7. 2015南阳CCPC C - The Battle of Chibi DP树状数组优化

    C - The Battle of Chibi Description Cao Cao made up a big army and was going to invade the whole Sou ...

  8. 【eJOI2020】考试(dp & 树状数组优化)

    Description \(n\) 个正整数排成一列,每个位置 \(i\) 有一个初始值 \(A_i\) 以及目标值 \(B_i\). 一次操作可以选定一个区间 \([l, r]\),并将区间内所有数 ...

  9. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

随机推荐

  1. Java使用Lettuce操作redis

    maven包 # 包含了lettuce jar <dependency> <groupId>org.springframework.boot</groupId> & ...

  2. PHP随手记2--获取随机n位不重复字符

    定义一个函数返回26英文字母中n位不重复随机字符 基本思路是利用内置函数生成随机数,取出该位置字母之后将其删除,再进行下一次随机,最后实现字符串拼接就ok! 代码很简单,通俗易懂,直接上代码吧: 1 ...

  3. 基于taro封装底下浮动弹窗组件

    先看效果图: jsx: import Taro, { Component } from '@tarojs/taro' import { View, Image } from '@tarojs/comp ...

  4. c++与c#混合编程

    C#写界面比较方便,而C++则擅长写算法,所以将两者结合起来将会加快程序的开发速度,并保证程序的质量.但C#与C++的混合编程有很多细节问题需要注意,下面简要列举一些并指出相应的解决办法. 1. 将本 ...

  5. C# 利用反射进行深拷贝

  6. 【转】互联网项目中mysql应该选什么事务隔离级别

    作者:孤独烟 转自:https://www.cnblogs.com/rjzheng/p/10510174.html 摘要 企业千万家,靠谱没几家.社招选错家,亲人两行泪. 祝大家金三银四跳槽顺利! 引 ...

  7. HDFS Shell基本操作

    1.目录操作 hdfs dfs [命令]  [命令]         等价于            hadoop fs []  [] 1  ./bin/hdfs dfs -mkdir -p /user ...

  8. Netty ServerBootstrap如何绑定端口

    这篇讲netty服务端ServerBootstrap如何启动 前言 BootStrap在netty的应用程序中负责引导服务器和客户端.netty包含了两种不同类型的引导: 使用服务器的ServerBo ...

  9. 从环境搭建到打包使用TypeScript

    目录 1.TypeScript是什么 2.TypeScript增加了什么 3.TypeScript环境的搭建 4.TypeScript的基本类型 5.TypeScrip编译选项 6.TypeScrip ...

  10. Linux网络编程:原始套接字简介

    Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...