zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    2019 SDN第二次上机作业
    2019 SDN上机第1次作业
    第五次软工作业结对编程
    JIRA中的核心概念
    产品经理与项目经理的区别
    掀起你的盖头来:浅谈项目管理办公室(PMO)
    你大概走了假敏捷:认真说说敏捷的实现和问题(手绘版)
    项目管理经验
    项目经理面试中可能遇到的问题
    回到网易8个月测试团队转型实践
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4799368.html
Copyright © 2011-2022 走看看