Forever Young

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;
}
posted @ 2020-09-08 21:02  Loceaner  阅读(152)  评论(0编辑  收藏  举报