[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.相邻两棵树间 ...
随机推荐
- Python装饰器使用技巧
装饰器 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多初次接触这个知识的人来讲,这个功能有点绕,自学时直接绕过去了,然后面试 ...
- Java中面向对象三大特性之继承
1. 继承的概述 继承就是子类继承父类的变量和方法,下面用代码解释一下: class Student {// 定义学生类 String name; int age; void study() { Sy ...
- php操作redis--有序集合(sorted set)篇
常用函数:zAdd,zRange,zRem,zCard等. 应用场景:类似集合,可以提供一个优先级的参数来为成员排序,如:分数 连接 $redis = new Redis(); $redis-> ...
- 深入理解MAGENTO – 第八章 – 深入MAGENTO的系统配置
(以下是原文) Last time we talked about Magento’s System Configuration system. If you missed it, you’ll wa ...
- PHP FILTER_VALIDATE_REGEXP 过滤器
定义和用法 FILTER_VALIDATE_REGEXP 过滤器根据兼容 Perl 的正则表达式来验证值. Name: "validate_regexp" ID-number: 2 ...
- (转)Vmware vSphere 5.0系列教程 vSphere网络原理及vSwitch简介 及一个host两个网卡说明
转:http://andygao.blog.51cto.com/323260/817518/ 在一个物理网络拓扑中,通常都是路由器-交换机-PC机的连接,不同的服务器和PC机,通过交换机的连接而相互连 ...
- 动态栈-------C语言
使用带头结点的单链表实现 主要使用链表中的头插来实现栈的先进后出的特点 /***************************************************** Author:Si ...
- CSS:CSS 语法
ylbtech-CSS:CSS 语法 1.返回顶部 1. CSS 语法 实例 查看 实例 1 查看 实例 2 CSS 实例 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: 选择器通常是 ...
- Dubbo入门到精通学习笔记(五):持续集成管理平台之sonarqube代码质量管理平台的介绍与安装
文章目录 SonarQube的介绍 SonarQube的安装 安装简介 详细安装过程 详细使用过程 SonarQube的介绍 SonarQube是一个管理代码质量的开放平台. 可以从七个维度检测代码质 ...
- mvn eclipse:eclipse
pom.xml 在哪个文件夹, 你就在哪里按shift 右键,,[在此处打开命令窗口] 执行那个命令. mvn eclipse:eclipse