【题解】CF#833 B-The Bakery
2024-09-04 12:57:47
一个非常明显的 \(nk\) dp 状态 \(f[i][k]\) 表示以 \(i\) 为第 \(k\) 段的最后一个元素时所能获得的最大代价。转移的时候枚举上一段的最后一个元素 \(j\)更新状态即可。考虑如何优化这个过程?主要的时间消耗在两个部分:一个是确定一段区间的贡献,另一个是找到最大的值。
这两个都是可以使用线段树来维护的,一段区间的贡献我们可以扫描线,而最大值则直接线段树维护最大值。如何滚动反而好像是最难的……想了一会儿,因为显然 memset 不可接受,然而我们可以 \(O(n)\) 建树啊……简直对自己的zz无语惹~
#include <bits/stdc++.h>
using namespace std;
#define maxn 2000000
#define maxm 40000
int n, K, ans, a[maxn], rec[maxn], last[maxn];
int f[maxm][]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct Segament_Tree
{
int mx[maxn], mark[maxn]; void Push_Down(int p)
{
mark[p << ] += mark[p], mark[p << | ] += mark[p];
mx[p << ] += mark[p], mx[p << | ] += mark[p];
mark[p] = ;
} void Build(int p, int l, int r, int K)
{
if(l == r) { mark[p] = , mx[p] = f[l - ][K]; return; }
int mid = (l + r) >> ;
mark[p] = ;
Build(p << , l, mid, K), Build(p << | , mid + , r, K);
mx[p] = max(mx[p << ], mx[p << | ]);
} void Update(int p, int l, int r, int L, int R, int x)
{
if(L <= l && R >= r) { mx[p] += x, mark[p] += x; return; }
if(L > r || R < l) return;
int mid = (l + r) >> ;
Push_Down(p);
Update(p << , l, mid, L, R, x);
Update(p << | , mid + , r, L, R, x);
mx[p] = max(mx[p << ], mx[p << | ]);
} int Query(int p, int l, int r, int L, int R)
{
if(L <= l && R >= r) { return mx[p]; }
if(L > r || R < l) return ;
int mid = (l + r) >> ;
Push_Down(p);
return max(Query(p << , l, mid, L, R), Query(p << | , mid + , r, L, R));
}
}T[]; int main()
{
n = read(), K = read();
for(int i = ; i <= n; i ++)
{
a[i] = read();
last[i] = rec[a[i]], rec[a[i]] = i;
}
int now = , pre = ;
for(int j = ; j <= K; j ++)
{
for(int i = ; i <= n; i ++)
{
T[pre].Update(, , n, last[i] + , i, );
f[i][j] = T[pre].Query(, , n, , i);
}
T[now].Build(, , n, j);
swap(now, pre);
}
printf("%d\n", f[n][K]);
return ;
}
最新文章
- css3控制标题字数超出的部分自动显示为“...”省略号
- 从CIO、CEO、CFO、COO...到CVO 这22个你了解几个? (史上最完整版)
- HDU(4528),BFS,2013腾讯编程马拉松初赛第五场(3月25日)
- SQL Server 字符串处理
- C#从数据库读取数据到DataSet并保存到xml文件
- 基于css3的文字3D翻转特效
- tomcat7 启动报错(转)
- java常用工具包
- NumPy学习_02 ndarray基本操作
- package-info.java的使用
- qemu对虚拟机的内存管理(二)
- 一个数组中两个数的和为N,找出这两个数字的下标
- C# 对密码等数据进行对称性加密解密
- Sql之left join(左关联)、right join(右关联)、inner join(自关联)的区别
- numpy---one
- Flash对象插入到网页中的3px问题
- 环信集成 2---基于环信Demo3.0,实现单聊功能
- JSON未定义
- nginx proxy模块
- php 修改图片分辨率
热门文章
- div仿textarea可输入
- 四、新时间日期API
- Linux怎样创建FTP服务器--修改用户默认目录-完美解决 - 费元星
- SpringBoot学习:整合shiro(rememberMe记住我功能)
- android 几个工具方法
- [CF294B]Shaass and Bookshelf
- 【if控制器】-(某种情况成立就执行的场景)
- Ubuntu—终端命令调整窗口的大小
- Fluent Python: Mutable Types as Parameter Defaults: Bad Idea
- rewrite or internal redirection cycle while processing nginx重定向报错