您的位置:首页 > 其它

HDU - 5726 GCD 数学 + 思维

2017-09-19 00:22 423 查看
传送门: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: