题意
给定一个序列,q次询问,每次问有多少连续子序列满足其最大公约数为这次询问的数
思路
因为最大公约数情况很少,所以我们用map记录一下以当前数为结尾最大公约数为几的有多少个,然后进行转移就好
代码
#include <cstdio>
#include <map>
using namespace std;
map<long long,long long> cnt1,cnt2,ans;
long long gcd(long long a,long long b)
{
if(a%b==0)
return b;
else if(b%a==0)
return a;
else if(a>b)
return gcd(b,a%b);
else return gcd(a,b%a);
}
int main()
{
long long n,a,q,x;
scanf("%I64d",&n);
for(long long i=0;i<n;i++)
{
scanf("%I64d",&a);
for(map<long long,long long>::iterator i=cnt1.begin();i!=cnt1.end();i++)
cnt2[gcd(i->first,a)]+=cnt1[i->first];
cnt2[a]++;
cnt1=cnt2;
for(map<long long,long long>::iterator i=cnt1.begin();i!=cnt1.end();i++)
ans[i->first]+=cnt1[i->first];
cnt2.clear();
}
scanf("%I64d",&q);
for(long long i=0;i<q;i++)
{
scanf("%I64d",&x);
printf("%I64d\n",ans[x]);
}
return 0;
}