CF2043C 题解

news/2024/12/25 12:07:14/文章来源:https://www.cnblogs.com/Hanggoash/p/18630101

CF2043C 题解

题意

给定一个除了 \(-1,1\) 之外,最多存在一个 \(x,x\in[-10^9,10^9]\) 的数的序列,求其子段和的所有可能值,从小到大输出。

分析

很容易就去思考如何从这个特殊的 \(x\) 入手。于是先排除这个特例,考虑全都是 \(1,-1\) 的情形,那么顺序从左到右不断加入 \(a_i\) ,可以发现可以通过维护当前值域的上下界来解决问题。最后我们对于 \(x\) 之前的数统计一遍, \(x\) 之后的数倒序统计一遍,然后通过 \(x\) 把两边合并起来就好了。

赛时就是这么想的,思路也大体正确了。

但是存在的一个问题是,值域中的某些数,可能并不能和当前这个 \(a_i\) 拼接到一起,因为它可能不是以 \(a_{i-1}\) 结尾的。比赛的时候是这么写的,很麻烦,最后也没有调出来。

值域统计

不妨换一个角度思考,一个 \([l,r]\) 的子段和可以表示为 \(sum_r-sum_{l-1}\),由于 \(x\) 比较特殊,我们还是像上文提到的那样对于 \(x\) 的两边分别统计,最后单独考虑 \(x\)

这样对于一个固定的 \(i\) 来说,\(sum_i-sum_j\) 的取值一定是在整数意义下连续的。因为任意的 \(sum_i\)\(sum_{i-1}\) 相比,绝对值只会相差 \(1\) ,这就是 \(1,-1\) 的带来的特殊性。(这段比较抽象,建议画一个 \(s_i\) 的散点图来理解)

所以只需要考虑前缀和的前缀 \(max\)\(min\) 就可以了,对于一个 \(s_i\)\([s_i-pmax,s_i-pmin]\) 之间的所有整数一定都是可以取到的,这样我们就成功计算出了以 \(a_i\) 为结尾的子段值域。

注意,这仅仅是以 \(a_i\) 为结尾的值域情况,我们不断维护它,是为了到最后能和 \(x\) 拼接起来,但是如果直接把它当成答案,肯定会有所遗漏,因为答案子段的结尾并不仅仅只是一个固定的元素,因此,对于所有算出来的值域,我们要取并集。

至于这个取并集过程的实现,观察到相邻两个元素的值域相差不会太大,我们只需要把每次更新值域后 被遗漏的部分提前标记为 true 就可以了。当然,在差分数组上操作,最后前缀和一遍的 trick 也是可以的。

以上是对于 \(x\) 左侧的计算方法,对于 \(x\) 的右侧来说,倒序枚举如法炮制即可。

\(x\) 两侧的值域进行合并

\(x\) 对应的下标为 \(pos\)

假设左边以 \(a_{pos-1}\) 为结尾的值域是 \([l,r]\),右边以 \(a_{pos+1}\) 为结尾的值域是 \([L,R]\)

很明显的是,最后能够取到的就是 \([x,x]\cup[l+x,r+x]\cup[L+x,R+x]\cup[l+L+x,r+R+x]\),把这一部分并进答案即可。

我个人的实现方法过于抽象,不过最后还是过了就行。

记得要单独把 \(0\) 也标记为 true。

Code

#include<bits/stdc++.h>
using namespace std;
int T,n;
const int N=2e5+10;
int a[N];
set<int> les,mor;
vector<int> output;
inline void out(set<int> &s){for(int x:s)cout<<x<<' ';}
inline void solve()
{cin>>n;les.clear(),mor.clear(),output.clear();vector<int> vis(2*n+10,0);auto upd=[&](int l,int r){for(int i=l;i<=r;++i){if(i<-n)les.insert(i);else if(i>n)mor.insert(i);else vis[i+n]=1;}};for(int i=1;i<=n;++i)cin>>a[i];int pos=n+1>>1;//随便钦定一个位置即可for(int i=1;i<=n;++i)if(a[i]!=1&&a[i]!=-1){pos=i;break;}int l=0,r=0,s=0;int mx=0,mn=0;for(int i=1,nowl,nowr;i<pos;++i){s+=a[i];nowl=s-mx,nowr=s-mn;for(int j=l;j<nowl;++j)vis[j+n]=1;for(int j=r;j>nowr;--j)vis[j+n]=1;mx=max(mx,s),mn=min(mn,s);l=nowl,r=nowr;}int L=0,R=0;s=0,mx=0,mn=0;for(int i=n,nowl,nowr;i>pos;--i){s+=a[i];nowl=s-mx,nowr=s-mn;for(int j=L;j<nowl;++j)vis[j+n]=1;for(int j=R;j>nowr;--j)vis[j+n]=1;mx=max(mx,s),mn=min(mn,s);L=nowl,R=nowr;}int x=a[pos];upd(l,r);upd(L,R);upd(x,x);upd(l+x,r+x);upd(L+x,R+x);upd(l+L+x,r+R+x);vis[n]=1;for(int i=-n;i<=n;++i)if(vis[i+n])output.push_back(i);cout<<les.size()+output.size()+mor.size()<<'\n';out(les);for(int val:output)cout<<val<<' ';out(mor);cout<<'\n';
}
int main()
{ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>T;while(T--)solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/858595.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杭州数据恢复之某公司经理的三星移动硬盘摔坏了盘片划伤二次开盘

这是一块老款三星Samsung使用mini USB接口的500G移动硬盘,采用了一体式电路板,型号是HM502JX。硬盘是用户不小心摔坏了,接电脑不识别而且有异响,先送修到百脑汇电脑城某家数据恢复中心进行开盘修复,但被告知盘片有划伤无法恢复数据。很巧用户公司里的一名员工曾经在我们这…

第十七次作业

1、安装最新版phpstudy集成工具并创建一个网站,编写php代码输出网站信息(phpinfo)2、安装vscode,并安装php开发插件、汉化插件、xdebug等插件 中⽂语⾔包安装php调试插件配置Open PHP/HTML/JS In Browser插件3、配置phpstudy集成工具xdebug扩展,并使用vscode对php代码进行…

dataezse接入zabbix监控

常用查询 目录常用查询zabbix 常用库表说明主机资源监控主机资源监控(纯值)oracle状态监控CPU top10DISK TOP 10Memory TOP 10SPACE USERD TOP 10问题告警级别分布问题列表null问题主机组正常主机总数主机问题排行 zabbix 常用库表说明 https://www.cnblogs.com/yaoyaojcy/p/…

MySQL 千万 级数据量根据(索引)优化 查询 速度

MySQL 千万 级数据量根据(索引)优化 查询 速度| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission | | -------------| -------------| -----…

kafka中文教程

kafka中文教程| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission | | -------------| -------------| -------------| -------------| -------…

银河麒麟桌面操作系统 使用root登录桌面端

麒麟 V10 桌面操作系统使用 root 登录 - 乔京飞 - 博客园 一、允许使用 root 用户登录 麒麟 V10 桌面操作系统安装过程后(或者安装完成后),必须创建一个新用户才能使用。很多目录中的文件,只能看不能改,甚至连创建一个新文件都不行。在终端执行命令,需要频繁的使用 sudo …

oracle exp 无法导出空表

oracle exp 无法导出空表| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission | | -------------| -------------| -------------| ------------…

好奇!J 人电商团队圣诞购物潮,哪 6 款办公软件是效率提升的秘密武器?

随着圣诞节的脚步日益临近,电商零售行业迎来了一年一度的业务高峰。对于 J 人特质鲜明的电商团队而言,高效的工作流程和团队协作机制是应对这一繁忙时期的关键所在。在众多办公软件中,可视化团队协作工具以其直观、高效的特点脱颖而出,成为提升工作效率和个人学习效率的得力…

车企售后服务中的项目管理创新:提升跨部门协作

一、引言 随着数字化技术的飞速发展,越来越多的车企开始向电商平台转型,不仅在销售端实现线上化,也将目光投向了售后服务的优化。传统的汽车售后服务模式主要依赖线下4S店,通过面对面的沟通和维修,服务流程相对固定,且服务质量参差不齐。随着消费者购车行为的逐渐转向线上…

Shiro550漏洞(CVE-2016-4437)

介绍 Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能。Shiro 框架直观、易用,同时也能提供健壮的安全性。 漏洞影响版本 Shiro <= 1.2.4 环境搭建 jdk:1.8.0_372 Tomcat8 这里我用的是 p 神的环境 https://github.com/phith0n/Jav…

Kubernetes应用编排控制器

1. Kubernetes控制器模式 1.1 声明式API API设计方法命令式API也称为指令式API,用户需要一步步地告诉机器该如何做(How),机器自身不具有任何“智能”,只被动接受指令 高度依赖用户自身理解和达成目标的能力和处理各类异常问题的经验,实现的是“命令式编程(Imperative Pr…