// clang-format off
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
#define FOR(i,l,r) for(auto i=(l);i<=(r);++i)
#define REP(i,n) FOR(i,0,(n)-1)
#define ssize(x) int(x.size())
auto operator<<(ostream&o,auto p)->decltype(p.first,o){return o<<"("<<p.first<<", "<<p.second<<")";}
auto operator<<(ostream&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";}
#ifdef DEBUG
#define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n'
#else
#define debug(...) {}
#endif
// clang-format on
vector<int> primes;
void
prepro_primes()
{
const int MAX_N = 316227;
const int MAX_N_SQRT = sqrt(MAX_N);
vector<bool> sieve(MAX_N + 1);
FOR (p, 2, MAX_N) {
if (sieve[p]) continue;
primes.emplace_back(p);
if (p > MAX_N_SQRT) continue;
for (int i = p * p; i <= MAX_N; i += p) sieve[i] = true;
}
}
bool check(const vector<int> &diffs, int k);
int
main()
{
cin.tie(0)->sync_with_stdio(0);
int N;
cin >> N;
vector<int> seq(N);
for (auto &x : seq) cin >> x;
// Generate sequence of differences
vector<int> diffs(N + 1);
diffs[0] = seq[0], diffs[N] = -seq[N - 1];
FOR (i, 1, N - 1) diffs[i] = seq[i] - seq[i - 1];
debug(diffs);
// K works => every divisor of K works
// prime p does not work => p !| K
// K has to be a divisor of sum, so I just check primes that divide sum
LL sum = accumulate(seq.begin(), seq.end(), (LL)0);
// sum may be a huge prime and K == sum
if (sum <= N and check(diffs, sum)) {
cout << sum << "\n";
return 0;
}
// List primes of sum
// need to only check primes K <= sqrt(sum) <= 316227
prepro_primes();
vector<int> sum_primes;
for (const auto &prime : primes) {
if (sum % prime == 0) sum_primes.emplace_back(prime);
}
debug(sum_primes);
// Throw out some primes
// assert(ssize(sum_primes) <= 11);
LL Kdivides = sum;
for (const auto &prime : sum_primes) {
if (prime <= N and check(diffs, prime)) continue;
while (Kdivides % prime == 0) Kdivides /= prime; // get rid of prime
}
// Check K
for (int k = N; k > 0; --k) {
if (Kdivides % k != 0) continue;
if (!check(diffs, k)) continue;
cout << k << "\n";
return 0;
}
cout << "1\n";
return 0;
}
bool
check(const vector<int> &orig_diffs, int k)
{
auto diffs = orig_diffs;
int N = ssize(diffs) - 1;
FOR (i, 0, N - k) {
if (diffs[i] < 0) return false;
diffs[i + k] += diffs[i];
}
FOR (i, N - k + 1, N)
if (diffs[i] != 0) return false;
return true;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | // clang-format off #include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r) for(auto i=(l);i<=(r);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) int(x.size()) auto operator<<(ostream&o,auto p)->decltype(p.first,o){return o<<"("<<p.first<<", "<<p.second<<")";} auto operator<<(ostream&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";} #ifdef DEBUG #define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n' #else #define debug(...) {} #endif // clang-format on vector<int> primes; void prepro_primes() { const int MAX_N = 316227; const int MAX_N_SQRT = sqrt(MAX_N); vector<bool> sieve(MAX_N + 1); FOR (p, 2, MAX_N) { if (sieve[p]) continue; primes.emplace_back(p); if (p > MAX_N_SQRT) continue; for (int i = p * p; i <= MAX_N; i += p) sieve[i] = true; } } bool check(const vector<int> &diffs, int k); int main() { cin.tie(0)->sync_with_stdio(0); int N; cin >> N; vector<int> seq(N); for (auto &x : seq) cin >> x; // Generate sequence of differences vector<int> diffs(N + 1); diffs[0] = seq[0], diffs[N] = -seq[N - 1]; FOR (i, 1, N - 1) diffs[i] = seq[i] - seq[i - 1]; debug(diffs); // K works => every divisor of K works // prime p does not work => p !| K // K has to be a divisor of sum, so I just check primes that divide sum LL sum = accumulate(seq.begin(), seq.end(), (LL)0); // sum may be a huge prime and K == sum if (sum <= N and check(diffs, sum)) { cout << sum << "\n"; return 0; } // List primes of sum // need to only check primes K <= sqrt(sum) <= 316227 prepro_primes(); vector<int> sum_primes; for (const auto &prime : primes) { if (sum % prime == 0) sum_primes.emplace_back(prime); } debug(sum_primes); // Throw out some primes // assert(ssize(sum_primes) <= 11); LL Kdivides = sum; for (const auto &prime : sum_primes) { if (prime <= N and check(diffs, prime)) continue; while (Kdivides % prime == 0) Kdivides /= prime; // get rid of prime } // Check K for (int k = N; k > 0; --k) { if (Kdivides % k != 0) continue; if (!check(diffs, k)) continue; cout << k << "\n"; return 0; } cout << "1\n"; return 0; } bool check(const vector<int> &orig_diffs, int k) { auto diffs = orig_diffs; int N = ssize(diffs) - 1; FOR (i, 0, N - k) { if (diffs[i] < 0) return false; diffs[i + k] += diffs[i]; } FOR (i, N - k + 1, N) if (diffs[i] != 0) return false; return true; } |
English