hdu 6287 口算训练
Posted kickit
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6287 口算训练相关的知识,希望对你有一定的参考价值。
题意:
小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计算这些问题的正确答案。
思路:
一开始bit套map 用前缀和处理,tle了?
对于每一个输入的数字,分解质因子,对于每一个质因子,把这个数字的位置push到这个质因子的vector里面去。
那么每一个vector里面的数字就是非递减的了。
然后对于每一个输入的l,r,d,把d分解质因子,对于每一个质因子,在这个质因子的vector里面找第一个大于等于l的位置和最后一个小于等于r的位置,相减,比较是否有d中这个质因子的数量多。
找的时候当然利用前面的非递减,所以可以二分。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <vector> 5 using namespace std; 6 const int N = 1e5 + 10; 7 8 vector<int> p; 9 vector<int> G[N],g[N]; 10 bool pp[N]; 11 int a[N]; 12 int n,m; 13 14 int main() 15 { 16 for (int i = 2;i < N;i++) 17 { 18 if (!pp[i]) 19 { 20 p.push_back(i); 21 for (int j = i * 2;j < N;j += i) 22 { 23 G[j].push_back(i); 24 pp[j] = 1; 25 } 26 } 27 } 28 int T; 29 scanf("%d",&T); 30 while (T--) 31 { 32 scanf("%d%d",&n,&m); 33 for (int i = 0;i < p.size();i++) 34 { 35 g[p[i]].clear(); 36 } 37 for (int i = 1;i <= n;i++) 38 { 39 int x; 40 scanf("%d",&x); 41 if (x == 1) continue; 42 if (!pp[x]) 43 { 44 g[x].push_back(i); 45 continue; 46 } 47 for (int j = 0;j < G[x].size();j++) 48 { 49 int cnt = 0; 50 int tmp = x; 51 int v = G[x][j]; 52 while (tmp % v == 0) 53 { 54 tmp /= v; 55 g[v].push_back(i); 56 } 57 } 58 } 59 while (m--) 60 { 61 int l,r,d; 62 scanf("%d%d%d",&l,&r,&d); 63 if (d == 1) 64 { 65 puts("Yes"); 66 continue; 67 } 68 if (!pp[d]) 69 { 70 int x = lower_bound(g[d].begin(),g[d].end(),l) - g[d].begin(); 71 int y = upper_bound(g[d].begin(),g[d].end(),r) - g[d].begin(); 72 y--; 73 if (y - x + 1 < 1) puts("No"); 74 else puts("Yes"); 75 } 76 else 77 { 78 bool f = 0; 79 for (int i = 0;i < G[d].size();i++) 80 { 81 int v = G[d][i]; 82 int cnt = 0; 83 int tmp = d; 84 while (tmp % v == 0) 85 { 86 cnt++; 87 tmp /= v; 88 } 89 int x = lower_bound(g[v].begin(),g[v].end(),l) - g[v].begin(); 90 int y = upper_bound(g[v].begin(),g[v].end(),r) - g[v].begin(); 91 y--; 92 if (y - x + 1 < cnt) f = 1; 93 if (f) break; 94 } 95 if (f) puts("No"); 96 else puts("Yes"); 97 } 98 } 99 } 100 return 0; 101 }
以上是关于hdu 6287 口算训练的主要内容,如果未能解决你的问题,请参考以下文章
2021年中国大学生程序设计竞赛 女生专场 - 热身赛 Problem C. 口算训练(质因子分解)
2021年中国大学生程序设计竞赛 女生专场 - 热身赛 Problem C. 口算训练(质因子分解)