【NOIP2013普及组复赛】题3:小朋友的数字

题3:小朋友的数字

【题目描述】

nnn 个小朋友排成一列。每个小朋友手上都有一个数字,这个数字可正可负。规定每个小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值。

作为这些小朋友的老师,你需要给每个小朋友一个分数,分数是这样规定的:第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。

请计算所有小朋友分数的最大值,输出时保持最大值的符号,将其绝对值对 ppp 取模后输出。

【输入】

第一行包含两个正整数 n、pn、pnp,之间用一个空格隔开。

第二行包含 nnn 个数,每两个整数之间用一个空格隔开,表示每个小朋友手上的数字。

【输出】

输出只有一行,包含一个整数,表示最大分数对 ppp 取模的结果。

【输入样例1】

5 997
1 2 3 4 5

【输出样例1】

21

【样例1说明】

小朋友的特征值分别为1、3、6、10、151、3、6、10、151361015,分数分别为 1、2、5、11、211、2、5、11、211251121,小朋友的特征值分别为对 997997997 的模是 212121

【输入样例2】

5 7
-1 -1 -1 -1 -1

【输出样例2】

-1

【样例2说明】

小朋友的特征值分别为−1、−1、−1、−1、−1−1、−1、−1、−1、−111111,分数分别为−1、−2、−2、−2、−2−1、−2、−2、−2、−212222,最大值 −1−11777 的模为 −1−11,输出 −1−11

【数据范围】

对于 50%50\%50%的数据,1≤n≤1,000,1≤p≤1,0001≤n≤1,000,1≤p≤1,0001n1,0001p1,000 所有数字的绝对值不超过 100010001000

对于 100%100\%100%的数据,1≤n≤1,000,000,1≤p≤1091≤n≤1,000,000,1≤p≤10^91n1,000,0001p109,其他数字的绝对值均不超过 10910^9109

【代码如下】:

#include <bits/stdc++.h>
using namespace std;
// ifstream cin("number.in");
// ofstream cout("number.out");
int i, n, p;
int num[1000001];
long long value[1000001];
long long area = 0, mark[1000001];
int main() {
  cin >> n >> p;
  for (i = 1; i <= n; i++) cin >> num[i];
  value[1] = num[1];
  for (i = 1; i <= n; i++) {
    area += num[i];
    value[i] = area;
    if (area < 0) area = 0;
  }
  for (i = 2; i <= n; i++)
    if (value[i] < value[i - 1]) value[i] = value[i - 1];
  mark[1] = value[1];
  mark[2] = mark[1] + value[1];
  bool flag = 0;
  for (i = 3; i <= n; i++) {
    mark[i] = mark[i - 1];
    if (value[i - 1] > 0) mark[i] += value[i - 1];
    if (mark[i] > mark[1]) flag = 1;
    if (flag == 1) mark[i] %= p;
  }
  if (flag == 1)
    cout << mark[n];
  else
    cout << mark[1];
  return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpstudio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值