题解:CF1547F Array Stabilization (GCD version)
解法比较抽象,但貌似比较快。
首先我们知道求
有点抽象,所以我举个例子
明白了这些,那么我们就有一个想法了,可以先将所有数扫一遍,求出每个质因子的最小指数,那么答案就是非最小指数到最小指数的距离。
因为
时间复杂度瓶颈在求质因数的最小指数,时间复杂度近似
code
#include<bits/stdc++.h>
#define aa a[i]
using namespace std;
const int N = 2e5 + 5, U = 1e6 + 5;
int n, a[N], p[N << 1], mn[N << 1], ans, cnt[N << 1];
bool book[U], book2[U], book3[U];
vector<int> mem;
struct node { int x, y; };
vector<node> num[N], lst;
inline void init() {
for(int i = 2; i < U; ++i) {
if(!book[i]) p[++p[0]] = i;
for(int j = 1; j <= p[0]; ++j) {
if(1ll * p[j] * i >= U) break;
if(book[p[j] * i]) break;
book[p[j] * i] = 1;
}
}
}
int main() {
init();
int t;
scanf("%d", &t);
while(t--) {
ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", a + i);
num[i].clear();
for(int j = 1; j <= p[0] && 1ll * p[j] * p[j] <= a[i]; ++j) {
int cnt1 = 0;
while(!(aa % p[j])) ++cnt1, aa /= p[j];
if(cnt1) {
++cnt[j], mem.push_back(j), mn[j] = mn[j] ? min(mn[j], cnt1) : cnt1;
num[i].push_back({j, cnt1});
}
}
if(aa ^ 1) {
int now = lower_bound(p + 1, p + p[0] + 1, aa) - p;
mem.push_back(now);
mn[now] = mn[now] ? min(mn[now], 1) : 1, ++cnt[now];
num[i].push_back({now, 1});
}
}
sort(mem.begin(), mem.end());
unique(mem.begin(), mem.end());
for(int i = mem.size() - 1; ~i; --i) {
int now = mem[i];
if(cnt[now] ^ n) mn[now] = 0, cnt[now] = 0;
}
for(int i = 1; i <= (n << 1); ++i) {
int ii = i % n;
ii = ii ? ii : n;
for(int j = num[ii].size() - 1; ~j; --j) {
node now = num[ii][j];
if(now.y ^ mn[now.x]) book2[now.x] = 1;
}
vector<node> mm;
while(!lst.empty()) {
node now = lst.back();
lst.pop_back();
if(!book2[now.x]) {
ans = max(ans, i - now.y);
}
else book3[now.x] = 1, mm.push_back(now);
}
for(int j = num[ii].size() - 1; ~j; --j) {
node now = num[ii][j];
if(!book3[now.x] && book2[now.x]) mm.push_back({now.x, i});
}
for(int i = mm.size() - 1; ~i; --i) {
int now = mm[i].x;
book2[now] = book3[now] = 0;
}
while(!mm.empty()) lst.push_back(mm.back()), mm.pop_back();
}
printf("%d\n", ans);
while(!mem.empty()) {
int now = mem.back();
mn[now] = cnt[now] = 0;
mem.pop_back();
}
}
return 0;
}