题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6287
题目:
口算训练
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 177 Accepted Submission(s): 41
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
1
5 4
6 4 7 2 5
1 2 24
1 3 18
2 5 17
3 5 35
Sample Output
Yes
No
No
Yes
思路:如博客题目所言,唯一分解定理+二分。首先将所有的a进行素数分解,然后用一个vector记录这个素数出现的位置(如x % i == 0, 此时x 是第8位数,那么p[i].push_back(8)),然后二分从d分解出来的素数在该区间内出现总次数是否大于它在d中的次数。
代码实现如下:
1 #include <cstdio> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 1e5 + 7; 7 int t, n, m, l, r, d, x; 8 9 vector<int> G[maxn]; 10 11 int check(int l, int r, int x) { 12 return upper_bound(G[x].begin(), G[x].end(), r) - lower_bound(G[x].begin(), G[x].end(), l); 13 } 14 15 bool slove(int l, int r, int x) { 16 for(int i = 2; i * i <= x; i++) { 17 int cnt = 0; 18 if(x % i == 0) { 19 while(x % i == 0) { 20 cnt++; 21 x /= i; 22 } 23 if(cnt > check(l, r, i)) { 24 return false; 25 } 26 } 27 } 28 if(x > 1) { 29 if(check(l, r, x) < 1) { 30 return false; 31 } 32 } 33 return true; 34 } 35 36 int main() { 37 scanf("%d", &t); 38 while(t--) { 39 scanf("%d%d", &n, &m); 40 for(int i = 0; i < maxn; i++) { 41 G[i].clear(); 42 } 43 for(int i = 1; i <= n; i++) { 44 scanf("%d", &x); 45 for(int j = 2; j * j <= x; j++) { 46 if(x % j == 0) { 47 while(x % j == 0) { 48 G[j].push_back(i); 49 x /= j; 50 } 51 } 52 } 53 if(x > 1) { 54 G[x].push_back(i); 55 } 56 } 57 while(m--) { 58 scanf("%d%d%d", &l, &r, &d); 59 printf("%s ", slove(l, r, d) ? "Yes" : "No"); 60 } 61 } 62 }