P3131 [USACO16JAN]Subsequences Summing to Sevens S
扯
菜狗 \(\text{sjp}\),真是太菜了
连前缀和都不会,甚至连 \(\text{while}\) 循环都不会用。
思路
前缀和
暴力 \(O(n^3)\) 必然不行。
直接前缀和然后 \(O(n^2)\) 也不行。
所以转枚举长度为枚举取模之后的值 \(0\sim 6\)。
一个小 \(\text{trick}\),如果有 \(i\le j\) 且 \(sum[i]\mod\ x=0,sum[j]\mod\ x=0\),那么 \((i,j]\) 区间的和 \(\mod x=0\)。
所以知道这个性质之后就很好做了,直接对前缀和取模然后找符合 \(x=\{0,1,2,3,4,5,6\}\) 时得到的最大区间,可以用两个端点值记录,详情看代码。
不会用while写/kk
复杂度 \(O(7\times n)\),可过。
代码
/*
Name: P3131 [USACO16JAN]Subsequences Summing to Sevens S
Author: Loceaner
Date: 08/09/20 19:55
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int A = 1e5 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int n, ans, a[A], sum[A];
int main() {
n = read();
for (int i = 1; i <= n; i++)
a[i] = read(), sum[i] = (sum[i - 1] + a[i]) % 7;
for (int i = 0; i <= 6; i++) {
int l = 1, r = n;
for ( ; l <= n; l++) if (sum[l] == i) break;
for ( ; r >= 1; r--) if (sum[r] == i) break;
ans = max(ans, r - l);
}
cout << ans << '\n';
return 0;
}
转载不必联系作者,但请声明出处