题目大意:
给多个区间的询问,在询问区间内每一个出现的素数去计算所有数中有多少个数能被这个素数整除
然后将所有素数得到的对应值求和
这里因为初始给定的数不超过10000000,最多670000不到的素数
而后面给定的区间到达1e9是没意义的,只要后面超过10000000都按最后一个数表示即可
然后将素数的标号作为树状数组的点,保存对应的点前缀和
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <ctime> 6 #include <cstdlib> 7 #include <vector> 8 #include <algorithm> 9 using namespace std; 10 #define ll long long 11 #define N 10001000 12 #define M 670000 13 #define pii pair<int,int> 14 #define lowbit(x) x&(-x) 15 int prime[M+5] , tot ; 16 bool check[N+5]; 17 18 void get_prim() 19 { 20 for(int i=2 ; i<=N ; i++){ 21 if(!check[i]) prime[tot++] = i; 22 for(int j=0 ; j<tot ; j++){ 23 if((ll)i*prime[j]>N) break; 24 check[i*prime[j]] = true; 25 if(i%prime[j]==0) break; 26 } 27 } 28 } 29 30 int Hash1(int x) 31 { 32 if(x>10000000) return 664580; //664579是10000000内素数的数目 33 int l=0 , r=tot-1 , ans=0; 34 while(l<=r){ 35 int m = (l+r)>>1; 36 if(prime[m]>=x){ans = m , r=m-1;} 37 else l=m+1; 38 } 39 return ans+1; 40 } 41 42 int Hash2(int x) 43 { 44 if(x>10000000) return 664580; 45 int l=0 , r=tot-1 , ans=0; 46 while(l<=r){ 47 int m = (l+r)>>1; 48 if(prime[m]<=x){ans = m , l=m+1;} 49 else r=m-1; 50 } 51 return ans+1; 52 } 53 54 ll sum[M]; 55 56 void add(int x , int v){for(int i=x ; i<=tot ; i+=lowbit(i)) sum[i] += v;} 57 58 ll query(int x) 59 { 60 ll ret = 0; 61 for(int i=x ; i>0 ; i-=lowbit(i)) ret+=sum[i]; 62 return ret; 63 } 64 65 void fenjie(int x) 66 { 67 int mx = (int)sqrt(x+0.5); 68 for(int i=0 ; i<tot ; i++){ 69 if(prime[i]*prime[i]>x) break; 70 if(x%prime[i]==0){ 71 // cout<<"in: "<<i<<" "<<prime[i]<<endl; 72 add(i+1 , 1); 73 while(x%prime[i]==0) x/=prime[i]; 74 } 75 } 76 if(x>1){ 77 int pos = lower_bound(prime , prime+tot , x)-prime; 78 add(pos+1 , 1); 79 } 80 } 81 82 int main() { 83 // freopen("a.in" , "r" , stdin); 84 // freopen("out.txt" , "w" , stdout); 85 get_prim(); 86 int n , m , s , t; 87 while(~scanf("%d" , &n)) 88 { 89 for(int i=0 ; i<n ; i++){ 90 int x ; 91 scanf("%d" , &x); 92 fenjie(x); 93 } 94 scanf("%d" , &m); 95 while(m--){ 96 scanf("%d%d" , &s , &t); 97 int p1 = Hash1(s) , p2 = Hash2(t); 98 // cout<<p1<<" "<<p2<<endl; 99 printf("%I64d\n" , query(p2)-query(p1-1)); 100 } 101 } 102 }
时间: 2024-10-06 07:03:16