rt,对着题解看了好久,不知道哪里错了。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, k, mx, a[N];
int divi[N * 10], lst[N], f[N], rmq[N][20];
//f[i] 为前 i 个数在最大公约数为 v 时最多能分成几段
vector<int> d;
stack<int> st;
bool cmp(int x, int y){return x > y;}
void update(int id, int val){
rmq[id][0] = val;
for(int i=1;(1<<i)<=id;i++) rmq[id][i] = max(rmq[id][i - 1], rmq[id - (1 << (i - 1))][i - 1]);
}
int query(int l, int r){
int m = log2(r - l + 1);
return max(rmq[r][m], rmq[l + (1 << m) - 1][m]);
}
int main(){
scanf("%d%d", &n, &k);
for(int i=1;i<=n;i++){
scanf("%d", &a[i]);
mx = max(mx, a[i]);
while(!st.empty() && a[i] >= a[st.top()]) st.pop();
if(!st.empty()) lst[i] = st.top();//单调栈优化,求出上一个比 a[i] 大的数
st.push(i);//入栈
}
for(int i=1;i*i<=mx;i++){
if(mx % i == 0){
d.push_back(i);
for(int j=1;j<=n;j++)
if(a[j] % i == 0)
divi[i]++;
if(i * i != mx){
d.push_back(mx / i);
for(int j=1;j<=n;j++)
if(a[j] % (mx / i) == 0)
divi[mx / i]++;
}
}
}//分解最大的数的质因数,因为其必定作为某个区间的最大值出现
sort(d.begin(), d.end(), cmp);//按因子从大到小排序
for(int v: d){
f[0] = 0, f[1] = 1;
update(1, f[1]);
for(int i=2;i<=n;i++){
if(a[i] % v != 0){
f[i] = f[lst[i]];
update(i, f[i]);
continue;
}
if(lst[i] == 0){//前缀最大值
int t = query(lst[i] + 1, i - 1);//找到前缀中的dp最大值
f[i] = (!t ? 0 : t + 1);
}
else{
int t = query(lst[i], i - 1);//从上一个比他大的数的位置开始取dp最大值
f[i] = (!t ? 0 : t + 1);//如果前面都分不成,显然后面的也不可能分成,记为 0
}
update(i, f[i]);//更新 dp 值到 ST 表中
}
if(divi[v] >= k && f[n] >= k)
return printf("%d\n", v), 0;
}
return 0;
}