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
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 }