hakerrank <Maximise Sum> set

关键词:前i-1个数中大于a[i]的最小值

题意:n个数,求模m的最大子序列(连续)和 

已知n和m

做法:1.预处理sum[i]=sum[i]%m(>0)

以第i个元素结尾的模m最大子序列和=max{sum[i],((sum[i]-x)%m+m)%m},x是前i-1个数大于sum[i]的最小值

如何维护前i-1个数种大于a[i]的最小值?——set


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;

const int maxn = 100000+10;

int t,n;
ll m;
ll a[maxn],sum[maxn],ans;

set<ll> s;

int main(){
    //freopen("a.txt","r",stdin);
    scanf("%d",&t);
    while(t--){
        scanf("%d%lld",&n,&m);
        sum[0]=0;
        for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); sum[i]=(a[i]+sum[i-1])%m; }
        s.clear();
        ans=0;
        for(int i=1;i<=n;i++){
            ll l=*s.upper_bound(sum[i]);
            ll tmp1=((sum[i]-l)%m+m)%m;
            ll tmp=max(tmp1,sum[i]);
            ans=max(tmp,ans);
            s.insert(sum[i]);
        }
        printf("%lld\n",ans);
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值