首页 > 其他 > 详细

D. Cut(倍增) from Codeforces Round #717 (Div. 2)

时间:2021-04-23 00:00:20      阅读:23      评论:0      收藏:0      [点我收藏+]

做法:记录每个点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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!