【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上的边,考 ...
随机推荐
- jmeter插件之jsonpath提取响应结果和做断言
准备工作: 1. jmeter3.X已经自带了提取响应结果的插件:JSON Extractor 2. 下载断言插件:https://jmeter-plugins.org/wiki/JSONPathAs ...
- 修改有数据oracle字段类型 从number转为varchar
--修改有数据oracle字段类型 从number转为varchar--例:修改ta_sp_org_invoice表中RESCUE_PHONE字段类型,从number转为varchar --step1 ...
- 4、shader透明测试(AlphaTest)
主要用于花草树木 用3D的Plane来实现透明的例子: 给Plane先赋予一个带alpha通道的透明图片,但是此图片此时是看不出来是透明的,如下: 现在我们要做的就是显示透明的效果:现在就用到了alp ...
- popen和system问题
popen和system问题 1. 问题描述 C的代码里面去调用命令启动一个shell脚本,分别使用了下面两个途径. 其中一个是: func1(cmd) { popen(cmd,type); pclo ...
- 条件随机场CRF
条件随机场(CRF)是给定一组输入随机变量X的条件下另一组输出随机变量Y的条件概率分布模型,其特点是假设输出随机变量构成马尔科夫随机场.实际上是定义在时序数据上的对数线性模型.条件随机场属于判别模型. ...
- 英特尔CEO科再奇:尚未发现通过漏洞获取用户数据的行为
1月9日消息,英特尔CEO科再奇在美国西部时间1月8日举行的2018年CES中发表主题演讲,他在开场时面向产业界谈到了最近报道的安全研究发现.科再奇表示:“在我们开始之前,我想借此机会感谢整个行业,为 ...
- java面笔准备
这套面试题主要目的是帮助那些还没有java软件开发实际工作经验,而正在努力寻找java软件开发工作的朋友在笔试时更好地赢得笔试和面试.由于这套面试题涉及的范围很泛,很广,很杂,大家不可能一天两天就看完 ...
- 关于debian配置的问题汇总
debian的apache多域名配置: https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-ho ...
- vue2.0介绍
1.vue.js 是什么 vue(view)是一套构建用户界面的渐进式框架 Vue (pronounced /vjuː/, like view) is a progressive framework ...
- ES 1.7安装ik分词elasticsearch-analysis-ik-1.2.5
IK简介 https://www.cnblogs.com/yjf512/p/4789239.html https://www.cnblogs.com/xing901022/p/5910139.html ...