[JZOJ6355] 【NOIP2019模拟】普 24/100
题目
题目大意
给你一个序列,对于所有\(k\in [1,n]\),求长度为\(k\)的子序列的最大权值,权值为\(a_1-a_2+a_3-...\pm a_k\)
思考历程
这题显然可以背包对吧……
所以就直接背包吧……
比赛的时候我还想到了分治,但由于两边合在一起很慢,所以就直接打暴力了。
正解
题解的线段树做法看得并不是很懂。
所以我就说一个分治的方法。
首先题解有个结论:\(k\)的子序列必然是\(k-2\)的子序列中插入两个数。
记住是插入,而不仅仅是往左右两边扩展。
为什么呢?考虑反证,如果不是这样,就是\(k-2\)的子序列中除去若干个数,然后再插入若干的数。这样实际上相当于从\(k-x\)的状态转移过来,其中\(x>2\)。
所以我们只需要证明从\(k-2\)转移过来比更前面的地方转移过来更优。
假设从\(k-3\)转移过来(其它的情况类似)。
我们将\(k-2\)的序列中按顺序插入\(x\)和\(y\),那么整个序列被分成几个部分\(AxByC\),权值为\(A\pm x-B\pm y+C\)(我们不需要关系\(x\)和\(y\)的正负,\(B\)是原本的贡献,在插入之后符号要翻过来)。
将\(k-3\)的序列中插入\(x\)和\(y\)和\(z\)(我们假设\(x\)和\(y\)插入的位置相同),分成:\(AxByDzE\),权值为\(A \pm x-B \pm y+D \pm z-E\)
比较一下,前半部分抵消了,就变成\(C\)和\(D \pm z-E\)
它们都可以看做一个整体。如果后面的更优,它肯定会在之前替代\(C\)。所以前者是更优一些的。
这就证完了。
然后考虑分治。分治的重点是合并左右两个区间的答案。
考虑由\(s\)转移到\(s+2\)。设转移\(s\)的时候左边用了\(s_1\)个,右边用了\(s_2\)个。
分类讨论看看新插入的两个点放哪边,就有如下三种情况:
- 左边\(s_1+2\),右边\(s_2\)。
- 左边\(s_1+1\),右边\(s_2+1\)
- 左边\(s_1\),右边\(s_2+2\).
根据上面的那个结论,前后两种情况是没有问题的。问题在于第二种情况。
由于是\(+1\),所以就不能用那个结论。
然而,我们发现,在左边\(s1\)或右边\(s2\)的状态中各插一个,其实也算在左边\(s1+1\)或右边\(s2+1\).的状态中。也就是说,\(s1+1\)的状态大于等于\(s1\)插一个转移过去的状态。
所以这样操作没有影响。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#define N 100010
int n,a[N];
int _fmn[N],_fmx[N];
int gmn[N],gmx[N];
inline int at(int *a,int x){return x?a[x]:0;}
void dfs(int l,int r){
int *fmn=_fmn+l-1,*fmx=_fmx+l-1;
if (l==r){
fmn[1]=fmx[1]=a[l];
return;
}
int mid=l+r>>1;
dfs(l,mid),dfs(mid+1,r);
int *lmn=_fmn+l-1,*lmx=_fmx+l-1,*rmn=_fmn+mid,*rmx=_fmx+mid,s1=0,s2=0;
for (int i=2;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MIN;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmx,s1)-at(rmn,s2+2):at(lmx,s1)+at(rmx,s2+2));
if (tmp>v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmx,s1+1)-at(rmn,s2+1):at(lmx,s1+1)+at(rmx,s2+1));
if (tmp>v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmx,s1+2)-at(rmn,s2):at(lmx,s1+2)+at(rmx,s2));
if (tmp>v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmx[i]=v;
s1=ts1,s2=ts2;
}
s1=0,s2=0;
for (int i=2;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MAX;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmn,s1)-at(rmx,s2+2):at(lmn,s1)+at(rmn,s2+2));
if (tmp<v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmn,s1+1)-at(rmx,s2+1):at(lmn,s1+1)+at(rmn,s2+1));
if (tmp<v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmn,s1+2)-at(rmx,s2):at(lmn,s1+2)+at(rmn,s2));
if (tmp<v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmn[i]=v;
s1=ts1,s2=ts2;
}
if (lmx[1]>rmx[1])
s1=1,s2=0,gmx[1]=lmx[1];
else
s1=0,s2=1,gmx[1]=rmx[1];
for (int i=3;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MIN;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmx,s1)-at(rmn,s2+2):at(lmx,s1)+at(rmx,s2+2));
if (tmp>v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmx,s1+1)-at(rmn,s2+1):at(lmx,s1+1)+at(rmx,s2+1));
if (tmp>v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmx,s1+2)-at(rmn,s2):at(lmx,s1+2)+at(rmx,s2));
if (tmp>v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmx[i]=v;
s1=ts1,s2=ts2;
}
if (lmn[1]<rmn[1])
s1=1,s2=0,gmn[1]=lmn[1];
else
s1=0,s2=1,gmn[1]=rmn[1];
for (int i=3;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MAX;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmn,s1)-at(rmx,s2+2):at(lmn,s1)+at(rmn,s2+2));
if (tmp<v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmn,s1+1)-at(rmx,s2+1):at(lmn,s1+1)+at(rmn,s2+1));
if (tmp<v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmn,s1+2)-at(rmx,s2):at(lmn,s1+2)+at(rmn,s2));
if (tmp<v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmn[i]=v;
s1=ts1,s2=ts2;
}
for (int i=1;i<=r-l+1;++i)
fmn[i]=gmn[i],fmx[i]=gmx[i];
}
int main(){
freopen("pe.in","r",stdin);
freopen("pe.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
dfs(1,n);
for (int i=1;i<=n;++i)
printf("%d ",_fmx[i]);
return 0;
}
总结
结论是要靠猜的……
[JZOJ6355] 【NOIP2019模拟】普 24/100的更多相关文章
- 2017冬季24集训模拟题-24星球的末日(Floyd)
24 星球的末日[问题描述]24 星球的世界末日就要到了 , 可是诺亚方舟还没有制造完成 . 为了制造诺亚方舟这个星球上的所有国家都站在统一战线 . 现在一共有n个国家 , 一个国家到另一个国家都有一 ...
- test20190815 NOIP2019 模拟题
100+60+40=200,被后面两个题卡着我很不爽. 立方数 [问题描述] 作为 XX 战队的狂热粉丝,MdZzZZ 看到了自己心仪的队伍在半决赛落败,顿时 心灰意冷.看着自己手中的从黄牛那里抢来的 ...
- test20190814 NOIP2019 模拟题
二叉树 [问题描述] 从前有一棵二叉树,我们用如下方式来表示这棵二叉树. 如果一个节点没有儿子,我们用"0"来表示他. 如果一个节点有一个儿子,我们对它的表示以"1&qu ...
- linux下模拟CPU占用100%小程序
在做一个测试时,需要模拟服务器CPU占用满的情况,在查阅相关资料后,发现网上程序不太好用, 原文在这:http://www.2cto.com/os/201304/202068.html 优化后如下: ...
- [考试反思]0817NOIP模拟测试24:冲淡
一切都还好吗? 是啊,还好. 前两名仍然被外校包揽/ B哥140撑住场面,120/110/100不等.我90分混吃等死排了个大并列第10. 考前说要考凸包,打开了几个博客慢慢看一直到考试开始. 然而我 ...
- test20190827 NOIP2019 模拟赛
100+100+50=250.最后那道期望题需要用另外的方式统计. 精灵加护 ljss 被 M 个敌人打倒在地上啦!每个敌人有一个威力值 bi.但是他手中还拥有 N 把武器!每把武器有一个威力值 ai ...
- test20190826 NOIP2019 模拟赛
100+100+40=240.我觉得如果没做过第三题考场上却能想出来的都是神仙. 基因突变 [问题描述] 邪恶的 707 刚刚从白垩纪穿越回来,心中产生了一个念头:我要统治人类! 但是统治人类是很庞大 ...
- test20190818 NOIP2019 模拟赛
0+0+20=20,不给大样例,小数据又水,还没有题解的垃圾题. A 题 问题描述: long long ago, Lxhgww 统治的国家里有 n 个城市,其中某一个城市是 capital (首都) ...
- test20190816 NOIP2019 模拟赛
100+100+20=220,T3吐槽:整个考室没有一个人正确地理解了题意. 树上路径(phantasm) Akari 的学校的校门前生长着一排 n 棵树,从西向东依次编号为 1 ∼ n.相邻两棵树间 ...
随机推荐
- Leetcode 200.岛屿的数量 - DFS、BFS
Leetcode 200 岛屿的数量: DFS利用函数调用栈保证了检索顺序, BFS则需要自己建立队列,把待检索对象按规则入队. class Solution { // DFS解法,8ms/10.7M ...
- PHP多参数方法的重构
假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子: <?php function saveArticle($title, $content, $categoryId ...
- 【Jenkins、sonar】
1.Jenkins入门(一)安装Jenkins 2.Jenkins入门(二)部署java项目 3.Jenkins远程部署SpringBoot应用 4.配置sonar.jenkins进行持续审查 5.S ...
- 数论+乱搞——cf181B
/* 2-type B|D^k 3-type B|D-1 11-type B|D+1 6-type B质因子分解, 7-type 其他情况 3-type: (a*(D^4-1)+b*(D^3-1)+. ...
- 安全检测及分析神器—AppScan使用教程
最近项目准备验收,所以最近在做项目验收的准备工作:我们公司规定,项目的安全检测必须通过才能进行项目验收:公司的安全部门用的检测软件就是大名鼎鼎的IBM Rational Appscan;在教由安全部门 ...
- [NOIP模拟测试11] 题解
A.string 和河北的一道省选题很像.考场上写的暴力桶排,正解其实就是优化一下这个思路. 开线段树维护字符串中每个字母出现的次数.对于每条询问,区间查询.区间赋值维护即可. 另外,本题卡常严重,正 ...
- Openstack组件部署 — Networking service_安装并配置Controller Node
目录 目录 前文列表 前提条件 网络环境 完成下面的步骤以创建数据库 创建service credentials服务凭证 创建Neutron的API Endpoints 配置自服务网络 安装网络组件 ...
- vbs 之 解决打开Excel文件格式与扩展名指定格式不一致的问题
' Q:解决打开Excel文件格式与扩展名指定格式不一致的问题' A: 使用工作簿saveAs时,往往忽略掉它的第二个参数FileFormat,添加即可. 比如: set bookDiff = oEx ...
- 2019牛客多校第三场H-Magic Line
Magic Line 题目传送门 解题思路 因为坐标的范围只有正负1000,且所有点坐标都是整数,所以所有点相连构成的最大斜率只有2000,而我们能够输出的的坐标范围是正负10^9.所以我们先把这n个 ...
- 『Golang』—— 标准库之 os
Golang 的 os 库基本承袭 Unix 下 C 语言的用法 path 库: func Base(path string) string //取文件名,不含目录部分 func Dir(path s ...