【STSRM12】夏令营
【题意】n个数划分成k段,每段的价值为段内不同数字的数量,求最大总价值
【算法】DP+线段树
【题解】
f[i][j]表示前i个数字划分成j段的最大价值。
f[i][j]=max(f[k][j-1]+value(k+1,j)),j-1<=k<i。
暴力复杂度O(n^3*k),预处理value后复杂度降为O(n^2*k)。
正解考虑加入一个数字i,只能为k+1~i贡献1的价值,其中k为数字i上一次出现的位置。
那么排序预处理上一次出现位置,区间+1用线段树维护,取max用线段树查询,复杂度O(nk*log n)。
注意线段树常数……特别注意手写max。
从头查比从中间查常数小。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
struct tree{int l,r,ms,delta;}t[maxn*];
struct cyc{int num,ord;}b[maxn];
bool cmp(cyc a,cyc b){return a.num<b.num||(a.num==b.num&&a.ord<b.ord);}
int f[maxn],n,kind,a[maxn],c[maxn];
void pushup(int k){t[k].ms=max(t[k<<].ms,t[k<<|].ms);}
void pushdown(int k){
if(t[k].delta){
t[k<<].delta+=t[k].delta;
t[k<<].ms+=t[k].delta;
t[k<<|].delta+=t[k].delta;
t[k<<|].ms+=t[k].delta;
t[k].delta=;
}
}
void build(int k,int l,int r){
t[k].l=l;t[k].r=r;
if(l==r){t[k].ms=f[l];t[k].delta=;}
else{
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
pushup(k);
t[k].delta=;
}
}
void insert(int k,int l,int r,int x){
if(l<=t[k].l&&t[k].r<=r){t[k].delta+=x;t[k].ms+=x;}
else{
pushdown(k);
int mid=(t[k].l+t[k].r)>>;
if(l<=mid)insert(k<<,l,r,x);
if(r>mid)insert(k<<|,l,r,x);
pushup(k);
}
}
int query(int k,int l,int r){
if(l<=t[k].l&&t[k].r<=r)return t[k].ms;
else{
pushdown(k);
int mid=(t[k].l+t[k].r)>>;
int ans=;
if(l<=mid)ans=query(k<<,l,r);
if(r>mid)ans=max(ans,query(k<<|,l,r));
return ans;
}
}
int main(){
scanf("%d%d",&n,&kind);
for(int i=;i<=n;i++){scanf("%d",&a[i]);b[i].num=a[i];b[i].ord=i;}
sort(b+,b+n+,cmp);
for(int i=;i<=n;i++)if(b[i].num==b[i-].num)c[b[i].ord]=b[i-].ord;
build(,,n);
for(int j=;j<=kind;j++){
for(int i=;i<=n;i++){
insert(,c[i],i-,);
f[i]=query(,,i-);
}
build(,,n);
}
printf("%d",f[n]);
return ;
}
暴力AC法:打表容易发现具有决策单调性,原因在于加入i时已知i-1的决策点j比左边优,加入i后对i上一次出现的位置到i有贡献,如果左边有贡献则j一定有贡献,所以决策点k>=j。
决策单调性可以用分支决策维护,复杂度O(n^2*k*log n)。
瓶颈在快速求区间数字个数,用主席树维护,复杂度O(nk*log n)。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=; int n,kind,f[][maxn],a[maxn],x,dfsnum=,b[maxn];
bool c[maxn];
int work(int x,int y){
dfsnum++;
int ans=;
for(int i=x;i<=y;i++)if(b[a[i]]!=dfsnum){
b[a[i]]=dfsnum;
ans++;
}
return ans;
}
void find(int l,int r,int L,int R)
{
if(l>r||L>R)return;
int mid=(l+r)>>;
int w,v=-inf+;
for(int i=L;i<=R&&i<mid;i++){
if(f[-x][i]+work(i+,mid)>v){
v=f[-x][i]+work(i+,mid);
w=i;
}
}
f[x][mid]=v;
find(l,mid-,L,w);
find(mid+,r,w,R);
}
int main()
{
scanf("%d%d",&n,&kind);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
x=;
for(int j=;j<=kind;j++){
x=-x;
f[x][]=-inf;
find(,n,,n-);
}
printf("%d",f[x][n]);
return ;
}
O(n^2*k*log n)
【STSRM12】夏令营的更多相关文章
- 【STSRM12】夏令营(分治决策单调+主席树)
[题意]n个数字分成k段,每一段的价值是段内不同数字的个数,求最大价值.n<=35000,k<=50. [算法]分治决策单调+主席树(可持久化线段树) [题解] f[i][j]表示前i天分 ...
- BUAA & ICT 夏令营之旅
我还只有二十几岁,总应该相信点什么吧. ================================ 7.10午后坐火车赶到北京.一路上火车行驶在茫茫云海里.车窗外的世界是这样子的:一片广袤的原野 ...
- Thu夏令营 总结
感觉这次thu夏令营简直就是爆RP啊 竟然签了无条件本一 [Waring]RP已空 话说这次考试设定 竟然是下午两点开始考试 考到五点- - 导致中午必须午睡 宾馆里清华也不近 按原本试机安排到12点 ...
- FZYZOJ-1578 [NOIP福建夏令营]数列分段
P1578 -- [NOIP福建夏令营]数列分段 时间限制:1000MS 内存限制:131072KB 状态:Accepted 标签: 二分 无 无 Descripti ...
- 值得赞扬的尝试与进步——CSDN开源夏令营第一印象
注:写这篇文章时我并未參加CSDN开源夏令营,也不确定是否会參加以及是否能參加上. 欣闻CSDN举办了"CSDN开源夏令营"活动.第一感觉是CSDN作为活动的组织者是很值得称赞的. ...
- 夏令营讲课内容整理 Day 7.
Day7是夏令营的最后一天,这一天主要讲了骗分技巧和往年经典的一些NOIP试题以及比赛策略. 这天有个小插曲,上午的day7T3是一道和树有关的题,我是想破脑袋也想不出来,正解写不出来就写暴力吧,暴力 ...
- 夏令营提高班上午上机测试 Day 3 解题报告
今天的题的确水.T3还是一道NOIP原题. 嘛,多刷点水题也不是什么坏事嘛. 说来也快,夏令营结束了整一星期了呢.大家也都回到了日常的暑假生活呢. 今天学业水平测试出成绩了...嗯结果还算满意呢,至少 ...
- 夏令营提高班上午上机测试 Day 2 解题报告
那一天,日照一中夏令营数据结构提高班的同学们终于想起了,被Day2上午的三道题支配的恐惧…… 是的..这一天的题有点难想.. 本来打算前天写这篇随笔,然而前天在机房和同学打luogu月赛…… 昨天 ...
- 浴谷夏令营例题Codeforces827DBest Edge Weight(三个愿望,一次满足~(大雾
这题在浴谷夏令营wyx在讲的最小生成树的时候提到过,但并没有细讲怎么写... 这题可以用三种写法写,虽然只有两种能过...(倍增/倍增+并查集/树链剖分 先跑出最小生成树,分类讨论,在MST上的边,考 ...
随机推荐
- nginx error_page
1. error_page语法 语法: error_page code [ code... ] [ = | =answer-code ] uri | @named_location 默认值: no 使 ...
- jackson 处理空值
@JsonInclude(value=Include.NON_NULL) public class ResultBean 这样在返回数据的时候, { "code": "s ...
- ardupilot_gazebo仿真(二)
ardupilot_gazebo仿真(二) 标签(空格分隔): 未分类 在模型中添加sensor gezebo官网-sensor部分教程 gezebo官网-基础部分教程 Gazebo plugins ...
- 从零开始搭建一个react项目
Nav logo 120 发现 关注 消息 4 搜索 从零开始搭建一个react项目 96 瘦人假噜噜 2017.04.23 23:29* 字数 6330 阅读 32892评论 31喜欢 36 项目地 ...
- ACM训练大纲
1. 算法总结及推荐题目 1.1 C++ STL • STL容器: set, map, vector, priority_queue, queue, stack, deque, bitset• STL ...
- Daily Scrum 11.01
全队进展速度很快,11月伊始都完成了初步的工作.交由负责整合工作的毛宇开始调试整合. Member Today's task Tomorrow's task 李孟 task 616 测试 (活动) ...
- Python-爬取"我去图书馆"座位编码
原文地址:http://fanjiajia.cn/2018/11/22/Python-%E7%88%AC%E5%8F%96%E2%80%9D%E6%88%91%E5%8E%BB%E5%9B%BE%E4 ...
- 【SSH】——Hibernate实现简单的自动建表
[与ORM] Object Relational Mapping,对象关系映射,将对象和关系联系了起来.面向对象是从耦合.聚合.封装等的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论 ...
- windbg*****************************TBD
achieve structure from a simple address Dt address know pending IRP in a module !thread xxxxxx到底能提供哪 ...
- StrutsResultSupport的使用
在有特殊情况时:如果没有异常信息,但是有错误并且有错误信息等内容:此时也需要进行友好的错误处理的话,那么可以借助StrutsResultSupport 返回结果类型来实现特定处理.此种方式先需要继承S ...