Maximum Subarray
提供一个复杂度与
容易发现的是,当
所以下文我们默认
我们先考虑最终选择所有长度
所以这一部分我们相当于要求
容易发现我们只需要枚举所有长度
接着第二部分,长度
于是我们枚举所有长度为
所以总体复杂度
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int t, n, k, x;
int a[N];
class SegmentTree
{
public:
struct Node
{
int l, r;
int sum, lmax, rmax, tmax;
Node()
{
l = r = sum = 0;
lmax = rmax = tmax = -1e11;
}
friend Node operator+(const Node& x, const Node& y)
{
Node p;
p.sum = x.sum + y.sum;
p.lmax = max(x.lmax, x.sum + y.lmax);
p.rmax = max(y.rmax, y.sum + x.rmax);
p.tmax = max({ x.tmax, y.tmax, x.rmax + y.lmax });
return p;
}
};
Node tree[N << 2];
void CLEAR(int n)
{
for (int i = 0; i <= 4 * n; i++)
{
tree[i].l = tree[i].r = 0;
tree[i].sum = 0;
tree[i].lmax = tree[i].rmax = tree[i].tmax = -1e11;
}
}
inline void push_up(int u)
{
int tl = tree[u].l, tr = tree[u].r;
tree[u] = tree[u << 1] + tree[u << 1 | 1];
tree[u].l = tl, tree[u].r = tr;
}
inline void build(int u, int l, int r, int *a)
{
tree[u].l = l, tree[u].r = r;
if (l == r)
{
tree[u].lmax = tree[u].rmax = tree[u].sum = tree[u].tmax = a[r];
}
else
{
int mid = (l + r) >> 1;
build(u << 1, l, mid, a);
build(u << 1 | 1, mid + 1, r, a);
push_up(u);
}
}
inline void modify(int u, int x, int v)
{
if (tree[u].l == x && tree[u].r == x)
{
tree[u].lmax = tree[u].rmax = tree[u].sum = tree[u].tmax = v;
}
else
{
int mid = (tree[u].l + tree[u].r) >> 1;
if (x <= mid) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
push_up(u);
}
}
Node query(int u, int l, int r)
{
if (tree[u].l >= l && tree[u].r <= r) return tree[u];
int mid = (tree[u].l + tree[u].r) >> 1;
Node x, y;
if (l <= mid) x = query(u << 1, l, r);
if (r > mid) y = query(u << 1 | 1, l, r);
return x + y;
}
}sgt;
signed main()
{
scanf("%lld", &t);
while (t--)
{
scanf("%lld%lld%lld", &n, &k, &x);
sgt.CLEAR(n);
if (x < 0)
{
x = -x;
k = n - k;
}
int ans = -1e18;
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
sgt.build(1, 1, n, a);
int i = k - 1;
if (i <= 0) goto E;
for (int j = 1; j <= i; j++)
{
sgt.modify(1, j, a[j] + x);
}
for (int j = 1; j + i - 1 <= n; j++)
{
ans = max(ans, sgt.query(1, j, j + i - 1).tmax);
sgt.modify(1, j, a[j]);
if (j + i <= n) sgt.modify(1, j + i, a[j + i] + x);
}
E:
long long f1 = 0LL, f2 = 0LL;
long long sum = 0LL, psum = 0LL;
for (int i = k + 1; i <= n; i++)
{
sum += (a[i] - x);
f2 = max(f2, sum);
}
for (int i = 1; i <= k; i++)
{
psum += a[i];
}
for (int i = 1; i + k - 1 <= n; i++)
{
ans = max(ans, psum + k * x + f1 + f2);
//printf("!: %lld %lld %lld\n", i, f1, f2);
f1 += (a[i] - x);
f1 = max(f1, 0LL);
if (f2 > 0) f2 -= (a[i + k] - x);
f2 = max(f2, 0LL);
psum -= a[i];
psum += a[i + k];
}
ans = max(ans, 0LL);
printf("%lld\n", ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现