Files
python/TangDou/CSP-J/AcWingTraining/T6/455.cpp

64 lines
1.9 KiB
C++
Raw Normal View History

2025-08-30 18:35:01 +08:00
#include <bits/stdc++.h>
// 使用标准命名空间
using namespace std;
// 定义__int128类型为LL,用于处理大数避免溢出
typedef __int128 LL;
// 定义常量N为1e6+10,适应题目数据范围
const int N = 1000010;
// 全局变量
int n, p; // n:小朋友数量 p:模数
LL f[N]; // f[i]:前i个小朋友的特征值(最大子段和)
// 自定义max函数,处理__int128类型
LL max(LL a, LL b) {
if (a >= b) return a;
return b;
}
int main() {
// 读取输入n和p
cin >> n >> p;
// 初始化变量
LL s = 0; // s:当前子段和
LL mx = -1e36; // mx:到目前为止的最大子段和
// 计算每个小朋友的特征值f[i]
for (int i = 1; i <= n; i++) {
int x; // 当前小朋友的数字
cin >> x;
// Kadane算法计算最大子段和
// 如果前面的子段和s为负,则舍弃,重新开始计算
s = max(s, 0) + x;
// 更新到目前为止的最大子段和
mx = max(mx, s);
// 保存前i个小朋友的特征值
f[i] = mx;
}
// 计算分数并找到最大值
LL res = f[1]; // res:记录最大分数,初始化为第一个小朋友的分数
LL score = f[1] * 2; // score:当前可转移的最大分数值
// 初始化为第一个小朋友分数的两倍,这是第二个小朋友可能获得的最大分数
// 遍历所有小朋友计算分数
for (int i = 2; i <= n; i++) {
// 更新最大分数
res = max(res, score);
// 如果当前特征值f[i]为正,则加入score,这样后续分数会更大
// 因为对于i+1到n的小朋友来说,选择i作为前面的小朋友时,分数会更大
if (f[i] > 0)
score += f[i];
}
// 输出结果:最大分数对p取模
printf("%lld\n", res % p);
return 0;
}