【BZOJ】4511: [Usaco2016 Jan]Subsequences Summing to Sevens 前缀和(特殊的技巧)
Description
Farmer John's N cows are standing in a row, as they have a tendency to do from time to time. Each cow is labeled with a distinct integer ID number so FJ can tell them apart. FJ would like to take a photo of a contiguous group of cows but, due to a traumatic childhood incident involving the numbers 1…6, he only wants to take a picture of a group of cows if their IDs add up to a multiple of 7.
Please help FJ determine the size of the largest group he can photograph.
The first line of input contains N(1≤N≤50,000). The next N lines each contain the N integer IDs of the cows (all are in the range 0…1,000,000
).
给定长度为N的数列A,求A最长的连续子序列,满足子序列中元素的和是7的倍数。输出最大的长度。如果不存在满
足条件的子序列,输出0。1 ≤ N ≤ 50000, 0 ≤ A_i ≤ 10 ^ 6
Input
Please output the number of cows in the largest consecutive group whose IDs sum to a multiple of 7. If no such group exists, output 0.
Output
You may want to note that the sum of the IDs of a large group of cows might be too large to fit into a standard 32-bit integer. If you are summing up large groups of IDs, you may therefore want to use a larger integer data type, like a 64-bit "long long" in C/C++.
Sample Input
7
3
5
1
6
2
14
10
3
5
1
6
2
14
10
Sample Output
5
In this example, 5+1+6+2+14 = 28.
In this example, 5+1+6+2+14 = 28.
题解:
题意比较明确了哈,考虑前缀和,区间l--r和能被7整除相当于(sum[r]-sum[l])%7==0,而要求最长区间的话只需要把每种余数都记录下来然后找到余数相同的最初和最末位置即可。
不加读入优化44ms,加上16ms rank3
code:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAXN = 50001; int a[MAXN], sum[MAXN], nxt[MAXN]; bool use[MAXN]; int n, m, cnt; char ss[1 << 25]; inline int read() { static char *c = ss; if (c == ss) fread(c, 1, 1 << 25, stdin); int u = 0; while (*c<48) ++c; while (*c>32) u = u * 10 + *c++ - 48; return u; } int main(int argc, char *argv[]) { int i, j, x, y; int ans = 0; n = read(); for (i = 1; i <= n; i++) { a[i] = read(); sum[i] = (sum[i - 1] + a[i])%7; use[sum[i]] = true; } if (n == 1 && a[1] % 7 == 0) { puts("1"); exit(0); } for (i = 0; i < 7; i++) { if (use[i] == false) continue; int l = 1, r = n; for (l = 1; l <= n; l++) if (sum[l] == i) break; for (r = n; r >= 1; r--) if (sum[r] == i) break; if (ans < r - l ) { ans = r - l ; } } printf("%d\n", ans); return 0; }
叶子的离去,是风的追求,还是树的不挽留?