题解
我们首先来分析小朋友的三个指标:手里的数,特征值,分数。
手里的数:即我们输入的长度为\(n\)的序列;
特征值:从第一个小朋友到当前小朋友的 手上的数 的 最大子段和;
分数:当前小朋友前面的小朋友中 小朋友特征值和分数的和 的最大值(第一个小朋友的分数等于其特征值)。
这个问题可以拆分成两个子问题。
一、求每个小朋友对应的最大子段和
最大子段和的核心思想
1.第一个数是一个有效子段。
2.如果 一个数加上上一个有效子段 的结果 大于 这个数,那么 这个数属于上一个有效子段。
3.如果 一个数加上上一个有效子段 的结果 小于 这个数,那么 这个数成为一个新的有效子段。
for(int i=1;i<=n;i++)
{
scanf("%lld",&hand);//hand是输入的手里的数
if(i==1) tmp[i]=hand;//tmp[]记录子段
else tmp[i]=maxx(hand,tmp[i-1]+hand);//取hand是第3种情况,取tmp[i-1]+hand是第2种情况
sub=maxx(sub,tmp[i]);//sub是第i个小朋友对应的最大子段和(特征值)
stu[i].spl=sub;
}
注意
sub=maxx(sub,tmp[i]);
stu[i].spl=sub;
不能写成
stu[i].spl=maxx(stu[i].spl,tmp[i]);
因为\(sub\)后续还会用到,所以需要持久地保存下来。
二、线性统计所有小朋友分数的最大值
第一个小朋友的分数就是其特征值。
第二个小朋友前面只有一个小朋友,所以第二个小朋友的分数就是第一个小朋友分数和特征值之和。
……
记录当前小朋友的分数为\(x\),那么下一个小朋友的分数就是 \(x\)、下一个小朋友与\(x\)的和 的最大值。、
stu[1].sco=stu[1].spl;
x=stu[1].sco+stu[1].spl;
ans=stu[1].sco;
for(int i=2;i<=n;i++)
{
stu[i].sco=x;
x=maxx(x,stu[i].spl+stu[i].sco);
ans=maxx(ans,stu[i].sco);
}
考虑到数据范围导致运算时会出现超过\(long long\)的值,所以可以使用__128来声明参与运算的变量,注意输入输出不能用__128。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const __int128 N=1000005;
const __int128 inf=2147483647;
ll n,p,hand;
__int128 x,ans;
struct student
{
__int128 spl,sco;
}stu[N];
__int128 tmp[N];
__int128 maxx(__int128 a,__int128 b)
{
return a>b?a:b;
}
__int128 sub=-inf;
ll final;
signed main()
{
//freopen("number.in","r",stdin);
//freopen("number.out","w",stdout);
scanf("%lld%lld",&n,&p);
for(int i=1;i<=n;i++)
{
scanf("%lld",&hand);//hand是输入的手里的数
if(i==1) tmp[i]=hand;//tmp[]记录子段
else tmp[i]=maxx(hand,tmp[i-1]+hand);//取hand是第3种情况,取tmp[i-1]+hand是第2种情况
sub=maxx(sub,tmp[i]);//sub是第i个小朋友对应的最大子段和(特征值)
stu[i].spl=sub;
}
stu[1].sco=stu[1].spl;
x=stu[1].sco+stu[1].spl;
ans=stu[1].sco;
for(int i=2;i<=n;i++)
{
stu[i].sco=x;
x=maxx(x,stu[i].spl+stu[i].sco);
ans=maxx(ans,stu[i].sco);
}
if(ans>=0)
{
ans=ans%p;
final=ans;
printf("%lld",final);
}
else
{
ans=-ans;
ans=ans%p;
final=ans;
printf("-%lld",final);
}
return 0;
}
标签:__,运算,子段,位位,记录,stu,ans,int128,小朋友
From: https://www.cnblogs.com/fish4174/p/16773010.html