做法:记录每个点i向左与它最近的不互质的数j,从j+1到i是可以分成1块的。
对于每次询问,从r开始一直贪心往前跳,每跳一步ans++;但这样一步一步跳会T,需要去倍增优化。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fastio ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
#define pii pair<int,int>
const int inf = 1e9 + 7;
const ll lnf = 1e18 + 7;
const int maxn = 1e5 + 10;
ll mod = 1e9 + 7;
int last[maxn], dp[25][maxn], f[maxn];//last:记录每个因子最后出现的位置
int main()
{
fastio;
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++)
{
f[i] = f[i - 1];
int x;
cin >> x;
for (int j = 2; j * j <= x; j++)
{
if (x % j == 0)
{
while (x % j == 0)
x /= j;
f[i] = max(f[i], last[j]);//去找最近的与x共因子的数(最近的不互质的数)
last[j] = i;
}
}
if (x != 1)
f[i] = max(f[i], last[x]), last[x] = i;
dp[0][i] = f[i];//跳1格
}
for (int i = 1; i <= 20; i++)
for (int j = 1; j <= n; j++)
dp[i][j] = dp[i - 1][dp[i - 1][j]];//倍增递推
while (q--)
{
int l, r;
cin >> l >> r;
int res = 0;
for (int j = 20; j >= 0; j--)
if (dp[j][r] >= l)
res += (1 << j), r = dp[j][r];
cout << res + 1 << endl;
}
return 0;
}
D. Cut(倍增) from Codeforces Round #717 (Div. 2)
原文:https://www.cnblogs.com/ruanbaiQAQ/p/14691572.html