标签:题解 长度 false pre lse mat sizeof \n 例题
欧拉筛可以\(O(n)\)筛素数,其本质是拿每个合数的最小质因子把这个合数筛掉。
void prime(int m) {
memset(flag, 1, sizeof flag);
cnt = 0;
for(int i=2; i<=m; i++) {
if(flag[i]) pr[++ cnt] = i;
for(int j=1; j<=cnt && i * pr[j] <= m; j++) {
flag[i * pr[j]] = 0;
if(i % pr[j] == 0) break ;
}
}
}
给定一个长度为\(n\)(\(n\)<=\(10^5\))的序列\(a\) (\(a_i <= 10^6\)),求最长的满足\(\prod_{i=l}^{r} a_i = lcm(a_l, a_{l+1}, \ldots, a_{r-1}, a_r)\)的子段长度.
欧拉筛线性筛出每个数的最小质因子,\(x\)的最小质因子在\(pr\)中的下标记为\(f(x)\),即\(x\)的最小质因子为\(pr_f(x)\)。
然后从\(1\)到\(n\)开始,记录右端点\(r\),尝试把\(a_r\)质因数分解加进去,直到加不进去,更新答案,把左端点向右移动一位。由于左右端点始终单调递增,复杂度\(O(n)\)。总的复杂度应该是预处理和求解:\(O(m+n log m)\),m表示\(a_i\)的上限\(10^6\)。因为质因数分解需要log的复杂度,每次除去最小质因子,直到\(1\)。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 100010;
const int MAXA = 1000010;
int n, a[MAXN], f[MAXA];
bool flag[MAXA];
int pr[MAXA], k[MAXA], cnt;
void prime(int m) {
memset(flag, 1, sizeof flag);
cnt = 0;
for(int i=2; i<=m; i++) {
if(flag[i]) pr[++ cnt] = i, f[i] = cnt;
for(int j=1; j<=cnt && i * pr[j] <= m; j++) {
flag[i * pr[j]] = 0;
f[i * pr[j]] = j;
if(i % pr[j] == 0) break ;
}
}
}
bool valid(int x) {
while(x > 1) {
if(k[ f[x] ]) return false;
x /= pr[f[x]];
}
return true;
}
void add(int x, int v) {
while(x > 1) {
k[ f[x] ] += v;
x /= pr[f[x]];
}
}
int main() {
prime(1e6);
int T; scanf("%d", &T);
for(int Case = 1; Case <= T; ++ Case) {
int ans = -1;
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d", &a[i]);
int r = 0;
for(int i=1; i<=n; i++) {
while(r < n && valid(a[r + 1])) add(a[++ r], 1);
ans = max(ans, r - i + 1);
add(a[i], -1);
}
if(ans < 2) ans = -1;
printf("Case %d: %d\n", ans);
}
return 0;
}
待填坑。
标签:题解 长度 false pre lse mat sizeof \n 例题
原文地址:https://www.cnblogs.com/cute-hzy/p/9378926.html