• CSU 1325 莫比乌斯反演


    题目大意:

    一、有多少个有序数对(x,y)满足1<=x<=A,1<=y<=B,并且gcd(x,y)为p的一个约数;

    二、有多少个有序数对(x,y)满足1<=x<=A,1<=y<=B,并且gcd(x,y)为p的一个倍数。

    第一行两个数:p和q。(1<p<10^7 ,1<q<1000。)

    接下来有q行,每行两个数A和B。(1<A,B<10^7)

    我们先考虑第二个问题 ,很简单答案就是 (A/p) * (B/p) , 因为从p开始每次叠加p枚举到A,B中间得到的数都是可以任意选择,gcd()的值必然是p的倍数的

    我们考虑第一个问题,这里约数的个数不超过数字n的2sqrt(n)个

    所以我们可以枚举出每一个约数k,然后对k进行求和

    对于使用莫比乌斯反演求和的话只是从当前来说复杂度大概是

    O(q*lg(p)*(sqrt(A)+sqrt(B))  //sqrt(A)是因为对莫比乌斯数组求前缀和进行快速计算,这是莫比乌斯中常出现的方式

    为了较低复杂度,我们列式计算考虑降维

    如下列公式所示:

    最后是如何计算sum[t],能计算出sum[]数组的话,t最大不超过min(A,B)那么总复杂度就能降为O(q*(sqrt(A)+sqrt(B))就没问题了

    这里t只跟k,d有关系,那么只要枚举每一个k,d就能得到sum[t]的数组了

    for(int i=0 ; i<cnt ; i++){
            for(int d=1 ; d*fac[i]<=M ; d++){
                sum[d*fac[i]] += mu[d];
            }
        }
    for(int i=1 ; i<=M ; i++) sum[i] += sum[i-1];

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <cmath>
     5 
     6 using namespace std;
     7 #define ll long long
     8 #define N 10005
     9 #define M 10000000
    10 int p,q,a,b,cnt;
    11 int fac[N];
    12 int mu[M+5] , prime[M/10] , tot , sum[M];
    13 bool check[M+5];
    14 
    15 void get_mu()
    16 {
    17     mu[1] = 1;
    18     for(int i=2 ; i<=M ; i++){
    19         if(!check[i]){
    20             mu[i] = -1;
    21             prime[tot++] = i;
    22         }
    23         for(int j=0 ; j<tot ; j++){
    24             if((ll)prime[j]*i>M) break;
    25             check[prime[j]*i] = true;
    26             if(i%prime[j]==0) break;
    27             else mu[i*prime[j]] = -mu[i];
    28         }
    29     }
    30 }
    31 
    32 void init()
    33 {
    34     int v = (int)sqrt(p+0.5);
    35     for(int i=1 ; i<=v ; i++){
    36         if(p%i==0){
    37             fac[cnt++] = i;
    38             if(p/i!=i) fac[cnt++] = p/i;
    39         }
    40     }
    41 }
    42 
    43 void pre_solve()
    44 {
    45     for(int i=0 ; i<cnt ; i++){
    46         for(int d=1 ; d*fac[i]<=M ; d++){
    47             sum[d*fac[i]] += mu[d];
    48         }
    49     }
    50     for(int i=1 ; i<=M ; i++) sum[i] += sum[i-1];
    51 }
    52 
    53 ll cal(int a , int b)
    54 {
    55     ll ans = 0;
    56     for(int t=1 , last ; t<=a ; t=last+1){
    57         last = min(a/(a/t) , b/(b/t));
    58         ans += (ll)(sum[last]-sum[t-1])*(a/t)*(b/t);
    59     }
    60     return ans;
    61 }
    62 
    63 int main()
    64 {
    65     get_mu();
    66     scanf("%d%d" , &p , &q);
    67     init();
    68     pre_solve();
    69     while(q--){
    70         scanf("%d%d" , &a , &b);
    71         if(a>b) swap(a , b);
    72         printf("%lld %lld
    " , cal(a,b) , (ll)(a/p)*(b/p));
    73     }
    74 }
     
  • 相关阅读:
    modis数据处理的坑(MOD02,mod03,mod04,MCD19A2)
    TensorFlow安装笔记(CPU版)
    mod35云掩膜产品用法
    ERA-Interim数据学习
    收集空气质量数据走的路
    GEE windows 环境配置
    Spatiotemporal continuous estimates of PM2.5 concentrations in China, 2000–2016: A machine learning method with inputs from satellites, chemical transport model, and ground observations
    Exploiting ConvNet Diversity for Flooding Identification
    Missing Data Reconstruction in Remote Sensing Image With a Unified Spatial–Temporal–Spectral Deep Convolutional Neural Network(缺失数据补全,时空谱网络)
    多线程
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4902748.html
Copyright © 2020-2023  润新知