题意概要

一个数组,最多有一个数的绝对值不是 \(1\),求出所有可以得到的区间和。

思路

这里提供一个 数据结构优化查询前缀和最值 的做法。

最多有一个数的绝对值不是 \(1\),那我们可以先忽略掉这个数(记该数下标为 \(x\))。

剩下的数要么是 \(1\),要么是 \(-1\),所以我们扩展一个区间的时候,区间和的变化(或增或减)单位大小是 \(1\)。

因此,我们最后的值一定是至多 \(2\) 个连续整数区间:

  • 一个是由 \(0\)(空区间) 扩展而来,并且扩展出的区间不包含 \(x\)。
  • 一个是由 \(a_x\) 扩展而来。

首先考虑第一种区间,我们求出不包含 \(x\) 的所有区间和的最大值和最小值即可。

这个很明显是一个区间最值问题,但是这里涉及到区间和,所以我们先把原数组 \(a\) 进行前缀和操作转化为前缀和数组 \(pre\)。

然后,我们把前缀和数组 \(pre\) 存入 线段树ST表 中维护区间前缀和最大值和最小值。

对于 \(x\) 左边的区间,我们从左到右枚举区间的左端点 \(i\),查询 \(i\) 到 \(x\) 的区间前缀和最大值,减掉 \(pre_{i - 1}\),就可以得到以 \(i\) 作为左端点的不包含 \(x\) 的所有区间的最大区间和。最小区间和同理。

对于 \(x\) 右边的区间,我们从左到右枚举区间的左端点 \(i\),查询 \(i\) 到 \(n\) 的区间前缀和最大值,减掉 \(pre_{i - 1}\),就可以得到以 \(i\) 作为左端点的不包含 \(x\) 的所有区间的最大区间和。最小区间和同理。

对于此类区间得到的结果取个并集,就是此类区间最后的结果。

然后是第二种区间,由 \(a_{x}\) 扩展而来。

此时这个区间一定包含 \(x\) ,因此,我们只需要以 \(x\) 为起点,分别向左向右扩展。

向左扩展变化的最小值加上向右扩展变化的最小值,就是此类区间的最小区间和。

向左扩展变化的最大值加上向右扩展变化的最大值,就是此类区间的最大区间和。

最后对两种区间求得的结果再取一个并集即可。

时间复杂度:\(O(n \log n)\)。

AC CODE

// Problem: C. Sums on Segments
// Contest: Codeforces - Educational Codeforces Round 173 (Rated for Div. 2)
// URL: https://codeforces.com/contest/2043/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h>
#define int long long
#define inf 2e18
#define ull unsigned long long
#define ls o << 1
#define rs o << 1 | 1 using namespace std; const int N = 2e5 + 9;
int a[N];
int tmx[N << 2], tmi[N << 2];
int n; //线段树维护区间最值
void pushup(int o)
{
tmx[o] = max(tmx[ls], tmx[rs]);
tmi[o] = min(tmi[ls], tmi[rs]);
} void build(int s = 1, int e = n, int o = 1)
{
if(s == e)return tmx[o] = a[s], tmi[o] = a[s], void(); int mid = s + e >> 1; build(s, mid, ls);
build(mid + 1, e, rs); pushup(o);
} int querymx(int l, int r, int s = 1, int e = n, int o = 1)
{
if(l <= s && e <= r) {
return tmx[o];
} int mid = s + e >> 1;
int res = -inf;
if(mid >= l)res = max(res, querymx(l, r, s, mid, ls));
if(mid + 1 <= r)res = max(res, querymx(l, r, mid + 1, e, rs)); return res;
} int querymi(int l, int r, int s = 1, int e = n, int o = 1)
{
if(l <= s && e <= r) {
return tmi[o];
} int mid = s + e >> 1;
int res = inf;
if(mid >= l)res = min(res, querymi(l, r, s, mid, ls));
if(mid + 1 <= r)res = min(res, querymi(l, r, mid + 1, e, rs)); return res;
} void solve()
{
cin >> n;
for(int i = 1;i <= n;i ++)cin >> a[i];
int ix = -1;
for(int i = 1;i <= n;i ++)
if(abs(a[i]) != 1)ix = i; for(int i = 1;i <= n;i ++)//前缀和
a[i] += a[i - 1]; build();//构建线段树 if(ix == -1)ix = n + 1; int nomi = 0, nomx = 0; //第一类区间
for(int i = 1;i <= n;i ++) {
if(i == ix)continue;
if(i <= ix) {
nomi = min(nomi, querymi(i, ix - 1) - a[i - 1]);
nomx = max(nomx, querymx(i, ix - 1) - a[i - 1]);
} else {
nomi = min(nomi, querymi(i, n) - a[i - 1]);
nomx = max(nomx, querymx(i, n) - a[i - 1]);
}
} //第二类区间
int hasmi = 0, hasmx = 0;
if(ix <= n) {
hasmi = a[ix] - a[ix - 1];
hasmx = a[ix] - a[ix - 1];
int lmi = 0, lmx = 0;
int rmi = 0, rmx = 0; int now = 0;
for(int i = ix - 1;i;i --) {
now += a[i] - a[i - 1];
lmi = min(lmi, now);
lmx = max(lmx, now);
} now = 0;
for(int i = ix + 1;i <= n;i ++) {
now += a[i] - a[i - 1];
rmi = min(rmi, now);
rmx = max(rmx, now);
} hasmi = hasmi + lmi + rmi;
hasmx = hasmx + lmx + rmx;
} set<int> ans; for(int i = nomi;i <= nomx;i ++)ans.insert(i);
for(int i = hasmi;i <= hasmx;i ++)ans.insert(i); cout << ans.size() << '\n';
for(auto &i : ans)cout << i << ' ';
cout << '\n';
} signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t = 1;cin >> t;
while(t --)solve(); return 0;
}

CF2043C Sums on Segments的更多相关文章

  1. Codeforces Round #575 (Div. 3) B. Odd Sum Segments (构造,数学)

    B. Odd Sum Segments time limit per test3 seconds memory limit per test256 megabytes inputstandard in ...

  2. B. Odd Sum Segments CF(分割数组)

    题目地址 http://codeforces.com/contest/1196/problem/B B. Odd Sum Segments time limit per test 3 seconds ...

  3. [LeetCode] Number of Segments in a String 字符串中的分段数量

    Count the number of segments in a string, where a segment is defined to be a contiguous sequence of ...

  4. [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

  5. Greenplum记录(一):主体结构、master、segments节点、interconnect、performance monitor

    结构:Client--master host--interconnect--segment host 每个节点都是单独的PG数据库,要获得最佳的性能需要对每个节点进行独立优化. master上不包含任 ...

  6. Application package 'AndroidManifest.xml' must have a minimum of 2 segments.

    看了源码就是packagename里面必须包含一个. 源码在: ./sdk/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/id ...

  7. segments&cache

    Segments 执行效果 命令  在 sense 里边执行  GET /abcd/_segments  前边的是索引名称,后边是请求 段信息 说明  索引是面向分片的,是由于索引是由一个或多个分片( ...

  8. UVA-11997 K Smallest Sums

    UVA - 11997 K Smallest Sums Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & ...

  9. [UCSD白板题] Points and Segments

    Problem Introduction The goal in this problem is given a set of segments on a line and a set of poin ...

  10. [UCSD白板题] Covering Segments by Points

    Problem Introduction You are given a set of segments on a line and your goal is to mark as few point ...

随机推荐

  1. git 报错 error: bad signature 0x00000000 fatal: index file corrupt

    index file在 git 里面一般指的是 .git/index 这个文件.这个文件保存的是暂存区的信息(索引信息). 报错说明这个文件已经损坏了 直接删除这个文件,然后执行如下命令 git re ...

  2. 动态 import()

    动态 import() https://v8.dev/features/dynamic-import Dynamic import() 引入了一个新的类似函数的功能,相比静态的 import 提供了新 ...

  3. 共建共荣金融生态!金融级数字底座“源启”与GoldenDB数据库完成互认证

    近日,中电金信金融级数字底座"源启"顺利与金篆信科GoldenDB分布式数据库完成互认证.GoldenDB数据库安全稳定运行在"源启"之上,整体性能表现卓越,进 ...

  4. Web components vs. React

    Web components vs. React - LogRocket Blog Web Components + Compose 是一条更好的路线. 当然,像 molecule 一样用 HTML ...

  5. 【Python】【爬虫】爬虫问题:requests的content和text

    爬虫问题:requests的content和text 通常来说,text获取的是Unicode编码的文本数据,content获取的是byte类型的二进制数据,比如获取图片本身.PDF文件之类的,可以用 ...

  6. Qt/C++地址转坐标/坐标转地址/逆地址解析/支持百度高德腾讯和天地图

    一.前言说明 地址和经纬度坐标转换的功能必须在线使用,一般用在导航需求上,比如用户输入起点地址和终点地址,查询路线后,显示对应的路线,而实际上各大地图厂家默认支持的是给定经纬度坐标来查询(百度地图支持 ...

  7. Qt开源作品42-视频监控布局

    一.前言 自从做监控系统以来,就一直有打算将这个功能独立出来一个类,这样的话很多系统用到此类布局切换,通用这个类就行,而且后期此布局会增加其他异形布局,甚至按照16:9之类的比例生成布局,之前此功能直 ...

  8. 基于开源IM即时通讯框架MobileIMSDK:RainbowChat v11.6版已发布

    关于RainbowChat RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统.RainbowChat源于真实运营的产品,解决了大量的屏幕适配.细节优化. ...

  9. 使用Docker编译PaddlePaddle

    在ubuntu中使用Docker编译PaddlePaddle 要在ubuntu中使用docker编译paddle框架,首先分为以下几个步骤: 安装docker环境 拉取paddle的docker镜像 ...

  10. CDS标准视图:一次性账户的客户行项目 I_ONETIMEACCOUNTCUSTOMER

    视图名称:一次性账户的客户行项目 视图类型:基础 视图代码: 点击查看代码 @EndUserText.label: 'One-Time Account Data for Customer Items' ...