小Q非常喜欢数学,但是他的口算能力非常弱。因此他找到了小T,给了小T一个长度为
nn的正整数序列
a1,a2,...,ana1,a2,...,an,要求小T抛出
mm个问题以训练他的口算能力。
每个问题给出三个正整数 l,r,dl,r,d,小Q需要通过口算快速判断 al×al+1×...×ar−1×aral×al+1×...×ar−1×ar是不是 dd的倍数。
小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。
Input第一行包含一个正整数
T(1≤T≤10)T(1≤T≤10),表示测试数据的组数。
每个问题给出三个正整数 l,r,dl,r,d,小Q需要通过口算快速判断 al×al+1×...×ar−1×aral×al+1×...×ar−1×ar是不是 dd的倍数。
小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。
每组数据第一行包含两个正整数 n,m(1≤n,m≤100000)n,m(1≤n,m≤100000),分别表示序列长度以及问题个数。
第二行包含 nn个正整数 a1,a2,...,an(1≤ai≤100000)a1,a2,...,an(1≤ai≤100000),表示序列中的每个数。
接下来 mm行,每行三个正整数 l,r,d(1≤l≤r≤n,1≤d≤100000)l,r,d(1≤l≤r≤n,1≤d≤100000),表示每个问题。Output对于每个问题输出一行,若是倍数,输出Yes,否则输出No。Sample Input
1 5 4 6 4 7 2 5 1 2 24 1 3 18 2 5 17 3 5 35Sample Output
Yes No No Yes
先用vector记录下每个因子出现的位置。vector里存的是含有i这个因子的下标。
查找l到r里因子个数时用upper_bound() - lower_bound()就可以。
#include<bits/stdc++.h>
using namespace std;
vector<int> a[100005];
int T, n, m;
void init(int x, int Index){
for(int i = 2; i * i <= x; i++){
if(x % i == 0){
while(x % i == 0){
x /= i;
a[i].push_back(Index);
}
}
}
if(x > 1)
a[x].push_back(Index);
}
int query(int l, int r, int x){
return upper_bound(a[x].begin(), a[x].end(), r) - lower_bound(a[x].begin(), a[x].end(), l);
}
int judge(int l, int r, int x){
for(int i = 2; i * i <= x; i++){
if(x % i == 0){
int t = 0;
while(x % i == 0){
x /= i;
t++;
}
int c = query(l, r, i);
if(t > c)
return 0;
}
}
if(x > 1 && query(l, r, x) < 1)
return 0;
return 1;
}
int main()
{
scanf("%d", &T);
while(T--){
for(int i = 0; i < 100005; i++)
a[i].clear();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
int x;
scanf("%d", &x);
init(x, i);
}
for(int i = 0; i < m; i++){
int l, r, d;
scanf("%d%d%d", &l, &r, &d);
int flag = judge(l, r, d);
if(flag)
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}