一开始是用线段树处理出来了这些东西,但是超时了,复杂度是
O
(
n
∗
log
3
n
)
O(n * \log^3 n)
O(n∗log3n).
但是,用 ST 表没有问题,因为 ST 表是
O
(
1
)
O(1)
O(1) 的查询时间(把
log
2
x
\log_2x
log2x 预处理出来就可以了).
#include<bits/stdc++.h>usingnamespace std;constint N =100010;typedeflonglong ll;
ll lg[N], a[N], f[N][20];int pw[30];int n;
ll query(int l,int r){int len = r - l +1;return__gcd(f[l][lg[len]], f[r - pw[lg[len]]+1][lg[len]]);}voidsolve(){
ll ans =0;for(int i =1; i <= n; i++){int st = i;
ll gcd = a[i];while(st <= n){
gcd =__gcd(gcd, a[st]);int l = st, r = n;while(l < r){int mid =(l + r +1)/2;if(query(i, mid)< gcd) r = mid -1;else l = mid;}
ans =max(ans,query(i, l)*(l - i +1));
st = l +1;}}printf("%lld\n", ans);}intmain(){for(int i =1; i < N; i++){
lg[i]=log2(i);}
pw[0]=1;for(int i =1; i <=20; i++){
pw[i]= pw[i -1]*2;}int T;scanf("%d",&T);while(T--){scanf("%d",&n);for(int i =1; i <= n; i++)scanf("%lld",&a[i]);for(int i =1; i <= n; i++) f[i][0]= a[i];for(int j =1; j <=18; j++){for(int i =1; i <= n; i++){if(i + pw[j]-1> n)break;
f[i][j]=__gcd(f[i][j -1], f[i + pw[j -1]][j -1]);}}solve();}return0;}