题目大意:给出一段区间,和一个树p,请找出一段区间,使得这段区间和%p的值最大。
思路:利用前缀和的思想,用set维护出现过的所有的前缀和。对于一个前缀和m来说,如果之前出现过(m + 1) % p是最好的,这样就可以达到最大。所以就找之前出现过比(m + 1)大的数,如果没有就贪心的取begin()。然后更新答案。
负数取模还是要好好搞搞。
CODE:
#include <set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 200010
using namespace std;
int cnt;
long long src[MAX],p;
set<long long> G;
int main()
{
cin >> cnt >> p;
long long ans = 0;
G.insert(0);
for(int i = 1; i <= cnt; ++i) {
scanf("%lld",&src[i]);
src[i] %= p;
if(src[i] < 0) src[i] += p;
src[i] = (src[i - 1] + src[i] % p) % p;
set<long long>::iterator it = G.lower_bound(src[i] + 1);
if(it == G.end()) it = G.begin();
ans = max(ans,(src[i] - *it + p) % p);
G.insert(src[i]);
}
cout << ans << endl;
return 0;
}