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 }
  • 相关阅读:
    dwr中的部分问题和总结
    UltraEdit常用快捷键
    Spring定时器StopWatch
    mybatis 教程(mybatis in action)
    Java中的session详解
    关于OutOfMemoryError的处理
    安卓版本和Api Level
    android通过adb wireless的使用
    adb端口被占用情况下如何杀掉进程
    解决Install failed uid changed
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4799368.html
Copyright © 2011-2022 走看看