bzoj 3544 [ONTAK2010]Creative Accounting 贪心

Description

给定一个长度为N的数组a和M,求一个区间[l,r],使得(\sum_{i=l}^{r}{a_i}) mod M的值最大,求出这个值,注意这里的mod是数学上的mod

Input

第一行两个整数N,M。
第二行N个整数a_i。

Output

输出一行,表示答案。

Sample Input

5 13
10 9 5 -5 7

Sample Output

11

HINT

【数据范围】
N<=200000,M,a_i<=10^18

题解

 

题解:因为,mod的最大值是其后者,或者第一个,

然后贪心即可,set维护,n log n

 1 #include<cstring>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<algorithm>
 6 #include<set>
 7 
 8 #define N 200007
 9 #define ll long long
10 using namespace std;
11 inline ll read()
12 {
13     ll x=0,f=1;char ch=getchar();
14     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
15     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 
19 ll n,m,ans;
20 ll a[N],sum[N];
21 set<ll>q;
22 
23 int main()
24 {
25     n=read(),m=read();
26     for (int i=1;i<=n;i++)a[i]=(read()%m+m)%m;
27     for (int i=1;i<=n;i++)(sum[i]=(sum[i-1]+a[i])%m+m)%=m;
28     q.insert(0);
29     for (int i=1;i<=n;i++)
30     {
31         ll t;
32         if (q.upper_bound(sum[i])==q.end()) t=*q.begin();
33         else t=*q.upper_bound(sum[i]);
34         ans=max(ans,((sum[i]-t)%m+m)%m);
35         q.insert(sum[i]);
36     }
37     printf("%lld",ans);
38 }

 

posted @ 2018-01-05 15:28  Kaiser-  阅读(171)  评论(0编辑  收藏  举报