题意概要

一个数组,最多有一个数的绝对值不是 \(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. django介绍及基本使用

    目录 一.python主流web框架 二.django简介 1.版本问题 2.运行django注意事项 三.django基本使用 1.下载模块 2.验证 3.常见命令 4.pycharm自动创建dja ...

  2. 【Word】文献引用批量上标

    \[([0-9]{1,2})\]

  3. kubeadm卸载清空k8s环境

    #!/bin/bash kubeadm reset -f modprobe -r ipip lsmod rm -rf ~/.kube/ rm -rf /etc/kubernetes/ rm -rf / ...

  4. Ubuntu中文件夹建立软链接方法

    1:预备知识 -s 是代号(symbolic)的意思. 这里有两点要注意:第一,ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化:第二,ln的链接又软链 ...

  5. Qt/C++音视频开发79-采集websocket视频流/打开ws开头的地址/音视频同步/保存到MP4文件/视频回放

    一.前言 随着音视频的爆发式的增长,各种推拉流应用场景应运而生,基本上都要求各个端都能查看实时视频流,比如PC端.手机端.网页端,在网页端用websocket来接收并解码实时视频流显示,是一个非常常规 ...

  6. Qt血的教训/细数Qt开发的各种坑/又爱又恨/欢迎围观留言评论

    一.吐槽总结 搞Qt开发十几年了,最初从Qt4.6开始,一直追新到现在的6.7版本,中间经历过无数的血的教训,简直是又爱又恨.其实Qt挺好的,但是还是要忍不住吐槽一下,本人还是希望Qt发展的越来越好, ...

  7. Qt/C++音视频开发48-推流到rtsp服务器

    一.前言 之前已经打通了rtmp的推流,理论上按照同样的代码,只要将rtmp推流地址换成rtsp推流地址,然后格式将flv换成rtsp就行,无奈直接遇到协议不支持的错误提示,网上说要换成rtp,换了也 ...

  8. C#程序如何把窗体文件从一个项目中复制到另一个项目

    一个窗体有三个文件,全部拷贝到新的项目中 在新的项目中点击显示所有文件,然后右击导入的文件,点击包括在项目中,会自动修改颜色(此时还没有被识别为窗体) 重启这个项目,三个文件已经被识别出来了 原文链接 ...

  9. 记录一下vue的插件

    2022.1.25今天记录下下载文件的插件  js-file-download  以防遗忘 首先npm install  js-file-download --save 其次引入import file ...

  10. CDS标准视图:应收账龄表 I_ARJrnlEntrItmAgingGrid

    视图名称:应收账龄表 I_ARJrnlEntrItmAgingGrid 视图类型:参数 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'IARJEITMAGGRID' ...