//#include<bits/stdc++.h> ----万能头----
#include <iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<cmath>
#include<queue>
#include<list>
#include<map>
#include<unordered_map>
#include<stack>
using namespace std;
//const int p = 1e9+7;
const int N = 2e3+5;
const int maxn = 1e5+5;
const long long INF = 1e18;
#define REP(i,n) for(ll i = 1; i <= n; ++i)
#define REPA(i,j,n) for(ll i = j; i <= n; ++i)
#define RREP(i,n) for(ll i = n; i >= 1; --i)
#define REPR(i,j,n) for(ll i = n; i >= j; --i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> PII;
typedef pair<double,ll> pdi;
ll t, n, m, k;
int a[maxn], ne[maxn],dp[20][maxn];
vector<int> p[maxn];
void solve(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; ++i)scanf("%d",&a[i]);
for(int i = 2; i <= maxn; ++i){
if(p[i].empty()){//如果当前数是素数
ne[i]=n+1;//对每个质数的ne初始化
for(int j = i ;j <= maxn; j += i)
p[j].push_back(i);//所有包含当前素数的数
}
}
dp[0][n+1] = n+1;//初始化
for(int i = n; i > 0; --i){//从后往前遍历,维护后段的质数信息
dp[0][i] = dp[0][i+1];//当前位置的最大贡献范围一定是小于等于其后一位的贡献范围
for(auto & j : p[a[i]]){//枚举当前数的质因子
dp[0][i] = min(dp[0][i],ne[j]);//更新当前位置的贡献范围
ne[j] = i;//更新质因子的出现位置
}
}
for(int i = 1; i < 20; ++i){//倍增预处理
for(int j = 1; j <= n+1; ++j)
dp[i][j]=dp[i-1][dp[i-1][j]];
}
for(int i = 1; i <= m; ++i){
int l, r , ans = 0;
scanf("%d%d",&l,&r);
for(int i = 19; i >= 0; --i){//跳啊跳
if(dp[i][l] <= r){
ans += (1<<i);
l = dp[i][l];
}
}
printf("%d\n",ans+1);//还有最后一步不能忘了计算
}
}
int main() {
//ios::sync_with_stdio(0);
//cin.tie(0);
//cout.tie(0);
#ifdef ACM
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
t = 1;
//scanf("%lld",&t);
while(t--)
solve();
fclose(stdin);
fclose(stdout);
}
1516D
最新推荐文章于 2021-07-12 15:30:07 发布