口算训练
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 1400 Accepted Submission(s): 279
Problem Description
小Q非常喜欢数学,但是他的口算能力非常弱。因此他找到了小T,给了小T一个长度为
n的正整数序列
a1,a2,...,an,要求小T抛出
m个问题以训练他的口算能力。
每个问题给出三个正整数 l,r,d,小Q需要通过口算快速判断 al×al+1×...×ar−1×ar是不是 d的倍数。
小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。
每个问题给出三个正整数 l,r,d,小Q需要通过口算快速判断 al×al+1×...×ar−1×ar是不是 d的倍数。
小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。
Input
第一行包含一个正整数
T(1≤T≤10),表示测试数据的组数。
每组数据第一行包含两个正整数 n,m(1≤n,m≤100000),分别表示序列长度以及问题个数。
第二行包含 n个正整数 a1,a2,...,an(1≤ai≤100000),表示序列中的每个数。
接下来 m行,每行三个正整数 l,r,d(1≤l≤r≤n,1≤d≤100000),表示每个问题。
每组数据第一行包含两个正整数 n,m(1≤n,m≤100000),分别表示序列长度以及问题个数。
第二行包含 n个正整数 a1,a2,...,an(1≤ai≤100000),表示序列中的每个数。
接下来 m行,每行三个正整数 l,r,d(1≤l≤r≤n,1≤d≤100000),表示每个问题。
Output
对于每个问题输出一行,若是倍数,输出Yes,否则输出No。
Sample Input
15 46 4 7 2 51 2 241 3 182 5 173 5 35
Sample Output
YesNoNoYes
题意:中文题目
思路:
1)运用:
1.vector (动态数组)
2.upper_bound (返回小于等于key的最后一个元素的后一个元素)
3.lower_bound (返回大于等于key的第一元素)
4.任何大于1的自然数,都可以唯一分解成有限个质数的乘积(唯一分解定理)
2)步骤:
1.将所给数组进行质因数分解,并且把数组标存入G[i]中。
//id原数组的下标,x原数组的值。eg:a[4]={2,3,4,5} prim(0,2) void prim(int id,int x){ for(int i=2 ; i*i<=x ;i++){ while(x%i==0){ G[i].push_back(id); x/=i; } } if(x>1){ G[x].push_back(id); } }
2.将查询的P也进行质因数分解,然后将每个质因数的个数与原数组区间对应质因数的个数比较
/*eg: a b 30 6 2,3,5 2,3 36 6 2,2,3,3 2,3 只要b全部的质因数都出现在a中,且相应质因数小于等于a中的, a就是b的倍数 */
3.注意,在处理质因数时(p函数),可能6/2=3,接着3没被处理。
//质因数分解+二分答案 #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+10; vector<int> G[maxn]; //id原数组的下标,x原数组的值。eg:a[4]={2,3,4,5} prim(0,2) void prim(int id,int x){ for(int i=2 ; i*i<=x ;i++){ while(x%i==0){ G[i].push_back(id); x/=i; } } if(x>1){ G[x].push_back(id); } } int main(){ int t; scanf("%d",&t); while(t--){ for(int i=0;i<maxn;i++) G[i].clear(); int n,m; int x; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&x); prim(i,x); } while(m--){ int l,r,p,flag=0,cnt; scanf("%d%d%d",&l,&r,&p); for(int i=2;i*i<=p;i++){ cnt=0; while(p%i==0){ cnt++; p/=i; } if(cnt){ int pos = upper_bound(G[i].begin(),G[i].end(),r)-lower_bound(G[i].begin(),G[i].end(),l); if(pos<cnt){ flag=1; } } } if(p>1){ int pos = upper_bound(G[p].begin(),G[p].end(),r)-lower_bound(G[p].begin(),G[p].end(),l); if(!pos){ flag=1; } } if(flag) puts("No"); else puts("Yes"); } } }