当前位置: 首页 > news >正文

题解:qoj14419 Maximum Segment Sum

清新小巧题!

题意:给出一个数 \(n\),求对于所有 \(k=[0,n]\),满足由 \(-1,1\) 构成的 \(n\) 长序列的最大子段和等于 \(k\) 的个数。

做法:

首先肯定考虑把答案改为算 \(\le k\) 的个数再差分得到答案。

考虑怎么求最大子段和,有柿子:\(s_i = \max(s_{i-1}+a_i,0)\)。那么如果没有这个取 \(\max\) 就是一个简单题,不过 \(y=k+1\) 这条线即可,但是有就很麻烦。

这里有个很天才的想法,我们考虑把整个坐标系对 \(y=-\frac1 2\) 反转,也就是我的 \(y\) 轴变成 \(\infty\cdots 2,1,0,0,1,2,\cdots \infty\)。两个 \(0\) 之间的移动就等于我取一次 \(\max\)。连续的取 \(\max\) 就等于我在 \(0\) 之间来回跳。这样的好处是,如果你取奇数次 \(\min\) 之后到了下平面,下半部分只要转上去就还是一个正常的路径,这样完美解决了 \(\max\)

然后我们没有必要用这个坐标系,还是用原来的坐标系上考虑,就等于可以到 \((i+1,j+1),(i+1,j-1)\),不能经过 \(y=k+1\)\(y=-k-2\),直接反射容斥即可。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6 + 5, mod = 998244353;
int n, jc[maxn], revjc[maxn], s[maxn];
int C(int m, int n) {return jc[m] * revjc[n] % mod * revjc[m - n] % mod;
}
void prepare() {jc[0] = revjc[0] = revjc[1] = 1;for (int i = 1; i <= n; i++)jc[i] = jc[i - 1] * i % mod;for (int i = 2; i <= n; i++)revjc[i] = (mod - mod / i) * revjc[mod % i] % mod;for (int i = 2; i <= n; i++)revjc[i] = revjc[i - 1] * revjc[i] % mod;for (int i = -n; i <= n; i += 2)s[i + n] = C(n, (n + i) / 2);for (int i = 1; i <= 2 * n; i++)s[i] = (s[i - 1] + s[i]) % mod;
}
int query(int st, int l, int r) {l -= st, r -= st;l += n, r += n;r = min(r, 2 * n), l = min(l, 2 * n + 1);return ((r >= 0 && r <= 2 * n ? s[r] : 0) - (l - 1 >= 0 && l - 1 <= 2 * n ? s[l - 1] : 0) + mod) % mod;
}
int lst = 0;
signed main() {cin >> n;prepare();for (int i = 0; i <= n; i++) {int k = i;int bg = 0, ans = query(bg, -k - 1, k);//cout << ans << endl;while(1) {bg = 2 * (k + 1) - bg;ans = (ans - query(bg, -k - 1, k) + mod) % mod;//		cout << bg << " " << query(bg, -k - 1, k) << " " << ans << endl;bg = -2 * (k + 2) - bg;ans = (ans + query(bg, -k - 1, k) + mod) % mod;if((k - bg) / 2 > n)break;}//		cout << ans << "debug"<< endl;bg = 0;while(1) {bg = -2 * (k + 2) - bg;ans = (ans - query(bg, -k - 1, k) + mod) % mod;bg = 2 * (k + 1) - bg;ans = (ans + query(bg, -k - 1, k) + mod) % mod;if((bg + k + 1) / 2 > n)break;}cout << (ans - lst + mod) % mod << " ";lst = ans;}cout << endl;return 0;
}
http://www.jsqmd.com/news/47086/

相关文章:

  • 20232310 2025-2026-1 《网络与系统攻防技术》实验七实验报告
  • 完整教程:基于Python楼王争霸劳动竞赛数据处理分析
  • 46
  • 2025.11.21博客
  • html导出pdf
  • 【第7章 I/O编程与异常】为什么句柄看起来像指针却不是指针?
  • SQL 基础语法
  • 实用指南:暖手宝方案开发,暖手宝MCU控制方案开发设计
  • NVM 与 单节点下PM2进程守护 安装配置以及使用教程完整指南(含 Node.js 环境搭建)
  • 北大六院的诊断
  • Pycharm远程连接服务器项目 - 实践
  • django项目前端模版文件,在pycahrm无法使用ctrl+alt+l格式化代码的解决办法
  • 北大六院后看又相
  • TPAMI 2025 | 从分离到融合:新一代3D场景技术建立双重能力提升!
  • 详细介绍:后端开发常用Linux命令
  • QT:Qt5.14向文档输出表格--编译异常信息
  • 《程序员修炼之道》阅读笔记5
  • java面向对象知识补充
  • 卷积神经网络的引入3 —— MLP 与 CNN 在更大数据集上的性能对比实验
  • 全网都在找的Nano Banana Pro API 来了!便宜稳定0.15/张
  • 通过DataReader获取sql查询的字段元数据信息
  • 2025.11.21 - A
  • 2025年新版ADB工具箱下载+驱动+ADB指令集+fastboot刷机ROOT程序
  • P7960 [NOIP2021] 报数__洛谷题解
  • 与括号序列相关的 DP 笔记
  • 【251121】CF2171 Div.3 vp 总结
  • OI 笑传 #32
  • PyOpenGL实现Bresenham算法
  • 【Linux】教你在 Linux 上搭建 Web 服务器,步骤清晰无门槛 - 详解
  • 【第7章 I/O编程与异常】\r\n 和 \n\r是一回事吗?