【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上的边,考 ...
随机推荐
- (1)分布式下的爬虫Scrapy应该如何做-安装
关于Scrapy的安装,网上一搜一大把,一个一个的安装说实话是有点麻烦,那有没有一键安装的?答案显然是有的,下面就是给神器的介绍: 主页:http://conda.pydata.org/docs/ 下 ...
- 关于redis一些问题记录
问题一:启动redis时出现警告,使用下列命令(已解决) 问题二:启动时,需要解决的警告(未解决) 问题三:使用自己的配置文件启动redis时,可能会遇到: Could not connect to ...
- Linux常用命令及搭建测试环境
题外话:三大操作系统------Linux.Unix.Windows,Unix系统如常见的Mac OS,Linux的很多命令跟Unix是通用的,所以就有一些开发人猿喜欢用苹果的原因.Linux发行版特 ...
- (Python爬虫01)-本想给随笔加个序号才发现这么不方便
本想给随机加个序号,才发现还得去返回看看文章的序号.好在cnblog能断点自动保存. 作为一个小程序员,点赞的同时还在想,谁知道咋实现这种实时保存呢?有知道的给个参考文档呗.太感激了! 重点在这里 有 ...
- CodeForces - 948C(前缀和 + 二分)
链接:CodeForces - 948C 题意:N天,每天生产一堆雪体积 V[i] ,每天每堆雪融化 T[i],问每天融化了多少雪. 题解:对 T 求前缀和,求每一堆雪能熬过多少天,再记录一下多余的就 ...
- 剑指offer-数值的整数次方12
class Solution: def Power(self, base, exponent): # write code here if base==0: return 0 if exponent= ...
- 并查集——poj1611(入门)
传送门:The Suspects 并查集水题 #include <iostream> #include <cstdio> #include <algorithm> ...
- Remix-Solidity IDE上run选项下Environment选择Web3 Provider,出现不能连接到测试网Ganache提示
解决办法:通常情况下,自己使用的浏览器IDE是:https://ethereum.github.io/browser-solidity,如果出现连接不到Ganache测试网的提示,可以使用另一种浏览器 ...
- Python标准模块logging
http://blog.csdn.net/fxjtoday/article/details/6307285 开发Python, 一直以来都是使用自己编写的logging模块. 比较土...... 今天 ...
- .Net com组件操作excel(不建议采用Com组件操作excel)
添加"Microsoft Office 12.0 Object Library" com组件 1 using System; using System.Data; using Sy ...