题面:
思路:
通过前缀和的思想,从0开始,当前值即为(sum+a[i])%p,用upper_bound查看map中是否有比当前值大的,如果有,那必然是比当前值少了k倍的p,那么起点则为upper出来的值,如果没有,则起点为0,比较当前(sum减去起点处的前缀和值加p)%p是否大于当前最大值,如果是则更换起点终点坐标以及最大值,同时将当前值和坐标存储进map,如此便可找到题目所需的最大值。
代码附下:
void solve()
{
ll n,p,sum=0;
cin>>n>>p;
map<ll,ll>mp;
array<ll,3>ans={0,0,0};
mp[0]=0;
for(ll i=1;i<=n;i++)
{
ll num;
cin>>num;
sum=(sum+num)%p;
auto it=mp.upper_bound(sum);
if(it==mp.end())it=mp.begin();
array<ll,3>fff={(sum-it->fs+p)%p,it->sc,i-1};
ans=max(ans,fff);
mp[sum]=i;
}
cout<<ans[1]<<" "<<ans[2]<<" "<<ans[0];
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
ll _=1;
// cin>>_;
while(_--)
solve();
return 0;
}
如有错误烦请指正谢谢

京公网安备 11010502036488号