傳送門: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;
}