【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3544
【题目大意】
找一段区间使得Σai mod m的值最大。
【题解】
首先计算前缀和顺序插入set,对于一个位置为右端点的数来说,
如果前缀的前缀和中有比其大的数,选择比其大的最小的那个计算用来更新答案一定最优
如果不存在,则选择set中最小的来计算更新答案。
【代码】
#include <cstdio> #include <algorithm> #include <set> using namespace std; const int N=200010; typedef long long LL; const LL INF=0x3f3f3f3f3f3f3f3f; int n; LL m,a[N],s[N]; int main(){ while(~scanf("%d%lld",&n,&m)){ for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); a[i]=(a[i]%m+m)%m; s[i]=(s[i-1]+a[i])%m; }LL t=0; LL ans=-INF; set<LL> st; st.insert(0); for(int i=1;i<=n;i++){ if(st.upper_bound(s[i])!=st.end())t=*st.upper_bound(s[i]); else t=*st.begin(); ans=max((s[i]-t+m)%m,ans); st.insert(s[i]); }printf("%lld ",ans); }return 0; }