HDU - 5726 GCD 數學 + 思維

傳送門:HDU 5726

題意:給定一段長度爲n的序列和m個詢問,每次詢問l,r區間的gcd是多少,和區間l,r的gcd相同的區間有多少個。

思路:HDU5869簡化版,詳見 點擊打開鏈接

代碼:

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define MAXN 100010
#define inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int>P;
map<int, ll> cnt;
int val[MAXN];
vector<P> p[MAXN];
int main()
{
	int T, n, sz, top, q;
	int l, r, tmp, ans, kase = 1;
	cin >> T;
	while(T--)
	{
		cnt.clear();
		scanf("%d", &n);
		for(int i = 1; i <= n; i++)
		scanf("%d", val + i), p[i].clear();
		for(int i = 1; i <= n; i++)
		{
			cnt[val[i]]++;
			p[i].pb(P(val[i], i));
			sz = p[i - 1].size();
			top = 0;
			for(int j = 0; j < sz; j++)
			{
				tmp = __gcd(val[i], p[i - 1][j].first);
				cnt[tmp] += p[i][top].second - p[i - 1][j].second;
				if(tmp == p[i][top].first)
				p[i][top].second = p[i - 1][j].second;
				else
				p[i].pb(P(tmp, p[i - 1][j].second)), top++;
			}
		}
		scanf("%d", &q);
		printf("Case #%d:\n", kase++);
		while(q--)
		{
			scanf("%d %d", &l, &r);
			sz = p[r].size();
			if(p[r][0].second <= l)
			ans = p[r][0].first;
			else
			for(int i = 1; i < sz; i++)
			if(p[r][i - 1].second > l && l >= p[r][i].second)
			{
				ans = p[r][i].first; break;
			}
			printf("%d %lld\n", ans, cnt[ans]);
		}
	}
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章