Description
One day,Little-Y saw many numbers standing in a row. A question suddenly appeared in her mind, ”From the L-th number to the R-th number, how many of them is a mutiple of P ? (P is a prime number) , and how quickly can I settle this problem ? ”
Input
Mutiple test cases. Please process till the end of file.
For each test case:
The first line contains two positive integers n and q (1<=n,q<=10^5), which means there are n integers standing in a row and q queries followed.
The second line contains n positive integers, a1,a2,a3,…,an (no more than 10^6) . Here, ai means the i-th integer in the row.
The next are q queries, each of which takes one line. For each query, there are three integers L,R,P (1<=L<=R<=n, 1<=P<=10^6, P is gurantteed to be a prime number). Their meanings have been mentioned in the discription.
Output
For each query, output the answer in one line.
Sample Input
6 5 12 8 17 15 90 28 1 4 3 2 6 5 1 1 2 3 5 17 1 6 999983
Sample Output
2 2 1 1 0
HINT
Source
题意:
给出一个数组
然后m个询问,每次询问l,r,p,询问数组l~r区间内有几个p的倍数
思路:
首先打出素数表,然后对于数组每个数分解质因子,将相同的质因子作为下标,存包含这些质因子的那些数的坐标,然后可以直接查询范围
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <math.h> #include <bitset> #include <list> #include <algorithm> #include <climits> using namespace std; #define lson 2*i #define rson 2*i+1 #define LS l,mid,lson #define RS mid+1,r,rson #define UP(i,x,y) for(i=x;i<=y;i++) #define DOWN(i,x,y) for(i=x;i>=y;i--) #define MEM(a,x) memset(a,x,sizeof(a)) #define W(a) while(a) #define gcd(a,b) __gcd(a,b) #define LL long long #define N 1000000 #define INF 0x3f3f3f3f #define EXP 1e-8 #define lowbit(x) (x&-x) const int mod = 1e9+7; vector<int> prime[N+5]; bool vis[N+5]; int pos[N+5],tot; void set() { int i,j; memset(vis,1,sizeof(vis)); for(i = 2; i<=N; i++) { if(vis[i]) { if(N/i<i) break; } for(j = (LL)i+i; j<=N; j+=i) vis[j] = 0; } tot = 1; for(i = 2; i<=N; i++) if(vis[i]) pos[i] = tot++; } int main() { set(); int i,j,n,m,x,y,l,r,L,R; while(~scanf("%d%d",&n,&m)) { for(i = 1; i<tot; i++) prime[i].clear(); for(i = 1; i<=n; i++) { scanf("%d",&x); for(j = 2; j*j<=x; j++) { if(x%j!=0) continue; prime[pos[j]].push_back(i); while(x%j==0) x/=j; } if(x>1) prime[pos[x]].push_back(i); } for(i = 1; i<tot; i++) sort(prime[i].begin(),prime[i].end()); while(m--) { scanf("%d%d%d",&l,&r,&x); y = pos[x]; int len = prime[y].size(); if(len==0||l>prime[y][len-1]||r<prime[y][0]) { printf("0\n"); continue; } L = lower_bound(prime[y].begin(),prime[y].end(),l)-prime[y].begin(); R = lower_bound(prime[y].begin(),prime[y].end(),r)-prime[y].begin(); if(R==len||prime[y][R]>r) R--; printf("%d\n",R-L+1); } } return 0; }