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
代码
O(n*log(n)) 卡不过去系列;
#include <bits/stdc++.h>
#define ll long long
#define N 200005
#define INF 0x7fffffff
struct NOTE
{
int l,r,key;
ll val;
}t[N*2];
ll a[N],sum[N];
int n,root,tot;
ll m,ans=-INF;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void rttr(int &dep)
{
int y=t[dep].l;
t[dep].l=t[y].r;
t[y].r=dep;
dep=y;
}
void rttl(int &dep)
{
int y=t[dep].r;
t[dep].r=t[y].l;
t[y].l=dep;
dep=y;
}
void insert(int &dep,ll x)
{
if(!dep)
{
dep=++tot;
t[tot].val=x;
t[tot].key=rand();
return ;
}
if(t[dep].val==x)
return ;
if(t[dep].val>x)
{
insert(t[dep].l,x);
if(t[t[dep].l].key<t[dep].key)
rttr(dep);
}
else
{
insert(t[dep].r,x);
if(t[t[dep].r].key<t[dep].key)
rttl(dep);
}
}
ll findMinm(ll x)
{
int dep=root;
ll y=0;
while(dep)
{
if(t[dep].val>x)
{
y=t[dep].val;
dep=t[dep].l;
}
else dep=t[dep].r;
}
return y;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
{
a[i]=(read()%m+m)%m;
sum[i]=(a[i]+sum[i-1])%m;
ans=std::max(ans,sum[i]);
}
for(int i=1;i<=n;i++)
{
ll ansn=findMinm(sum[i]);
if(ansn)
ans=std::max(ans,((sum[i]-ansn)%m+m)%m);
insert(root,sum[i]);
}
printf("%lld\n",ans);
}