题解:AT_pakencamp_2020_day1_k Gcd of Sum
把连续的子序列看成子序列的说是。
记
将
所以
对于一个二元组
于是,我们只需要对于每一个
由于这里是连续子序列(即子串),所以可以做一遍前缀和然后差分得到子串和。
记
因为有
时间复杂度:
引用一下 035966_L3 写的文章里面的这个图片:
知道当
:::success[代码]
ATcoder 提交记录。
/*
Start Code At 2026/7/25 7:59:11 .
Code by Bestart (luogu uid : 1062290) .
*/
#include <bits/stdc++.h>
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , fread_cnt , stdin) , p1 == p2) ? EOF : *p1 ++)
using namespace std ;
using db = double ;
using i128 = __int128 ;
using ll = long long ;
using ldb = long double ;
using uint = unsigned int ;
using ui128 = unsigned __int128 ;
using ull = unsigned long long ;
#define inline
//#define int long long
mt19937 rnd( chrono :: system_clock :: now() .time_since_epoch() .count() ) ;
const uint fread_cnt = 1 << 20 | 10 ;
const uint mod = 998244353 ;
const uint MN = 2e3 + 10 ;
const int inf = 1e9 + 7 ;
//const ll inf = 1e18 ;
char buf[fread_cnt] , *p1 = buf , *p2 = buf ;
template <typename T = int>
inline T read()
{
bool f = 0 ; T x = 0 ; char ch = gc() ;
while(ch < '0' || ch > '9') f ^= ch == '-' , ch = gc() ;
while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + (ch ^ 48) , ch = gc() ;
return f ? -x : x ;
}
uint n , a[MN] , cnt ;
ull s[MN] , p[MN] , b[MN] , res[MN] ;
inline void work (ull x)
{
for(ull i = 1 ; i*i <= x ; ++ i)
{
if(x % i == 0)
{
p[++ cnt] = i ;
if(x != i*i) p[++ cnt] = x/i ;
}
}
}
inline bool solve()
{
cin >> n ;
for(uint i = 1 ; i <= n ; ++ i) cin >> a[i] , s[i] = s[i-1]+a[i] ;
work(s[n]) ;
for(uint i = 1 ; i <= cnt ; ++ i)
{
uint tot = 0 ;
for(uint j = 1 ; j <= n ; ++ j) tot += s[j]%p[i]==0 ;
res[tot] = max(res[tot] , p[i]) ;
}
for(uint i = n ; i >= 1 ; -- i) res[i] = max(res[i] , res[i+1]) ;
for(uint i = 1 ; i <= n ; ++ i) cout << res[i] << '\n' ;
return 0 ;
}
signed main()
{
// freopen("aggravate.in" , "r" , stdin) ;
// freopen("aggravate.out" , "w" , stdout) ;
cin.tie(0) -> sync_with_stdio(0) ;
// system("fc aggravate.out aggravate3.ans") ;
// int t = 1 ; cin >> t ; while(t --) solve() ;
// while(!solve()) ;
solve() ;
return 0 ;
}
:::
:::info[短小精悍版]
#include <bits/stdc++.h>
using namespace std ;
const int MN = 2e3 + 10 ;
int n , a[MN] , cnt ;
long long s[MN] , p[MN] , b[MN] , res[MN] ;
signed main() {
cin.tie(0) -> sync_with_stdio(0) ;
cin >> n ;
for(int i = 1 ; i <= n ; ++ i) cin >> a[i] , s[i] = s[i-1]+a[i] ;
for(long long i = 1 ; i*i <= s[n] ; ++ i) if(s[n] % i == 0) {
p[++ cnt] = i ;
if(s[n] != i*i) p[++ cnt] = s[n]/i ;
}
for(int i = 1 ; i <= cnt ; ++ i) {
int tot = 0 ;
for(int j = 1 ; j <= n ; ++ j) tot += s[j]%p[i]==0 ;
res[tot] = max(res[tot] , p[i]) ;
}
for(int i = n ; i >= 1 ; -- i) res[i] = max(res[i] , res[i+1]) ;
for(int i = 1 ; i <= n ; ++ i) cout << res[i] << '\n' ;
return 0 ;
}
:::