1. 程式人生 > 實用技巧 >P3131 [USACO16JAN]Subsequences Summing to Sevens S

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;
}