题意:一个n个数(1 ≤ n ≤ 10^5)的序列,q个询问(1 ≤ q ≤ 3 × 10^5),每个询问是一个数x,对于每个询问,输出gcd(ai, ai+1, ..., aj) == x的(i, j)对数。
题目链接:http://codeforces.com/contest/475/problem/D
——>>枚举一次。。
为什么不会TLE呢?因为每趟子枚举基于上一趟的产生的最大公约数个数cnt,yy一下,这个cnt不会很大。。
注意:结果可超32位整数范围!
#include <cstdio>
#include <map>
#include <algorithm>
using std::map;
using std::swap;
const int MAXN = 100000 + 1;
const int MAXQ = 300000 + 1;
int a[MAXN];
map<int, long long> mpRet;
void Read(int n)
{
for (int i = 1; i <= n; ++i)
{
scanf("%d", a + i);
}
}
int Gcd(int a, int b)
{
return a % b == 0 ? b : Gcd(b, a % b);
}
void GetRet(int n)
{
map<int, int> mpCur;
map<int, int> mpBuf;
mpRet.clear();
for (int i = 1; i <= n; ++i)
{
mpBuf.clear();
for (map<int, int>::const_iterator iter = mpCur.begin(); iter != mpCur.end(); ++iter)
{
int nGcd = Gcd(iter->first, a[i]);
mpBuf[nGcd] += iter->second;
}
mpBuf[a[i]]++;
swap(mpCur, mpBuf);
for (map<int, int>::const_iterator iter = mpCur.begin(); iter != mpCur.end(); ++iter)
{
mpRet[iter->first] += iter->second;
}
}
}
int main()
{
int n, q, x;
while (scanf("%d", &n) == 1)
{
Read(n);
GetRet(n);
scanf("%d", &q);
while (q--)
{
scanf("%d", &x);
printf("%I64d\n", mpRet[x]);
}
}
return 0;
}