Codeforce385C 树状数组+素因子分解

 题目大意:

给多个区间的询问,在询问区间内每一个出现的素数去计算所有数中有多少个数能被这个素数整除

然后将所有素数得到的对应值求和

这里因为初始给定的数不超过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
" , query(p2)-query(p1-1));
100         }
101     }
102 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/4799368.html