• P2257 YY的GCD


    链接

    思路

    题目要求
    $sumlimits_{i=1}^nsumlimits_{j=1}^m [(i,j)为素数]$

    枚举一个素数,考虑它的贡献

    $sumlimits_psumlimits_{i=1}^{n}sumlimits_{j=1}^{m} [(i,j)=p]$

    后面的利用bzoj 1101的做法。

    $sumlimits_psumlimits_{i=1}^{lfloorfrac{n}{p} floor}sumlimits_{j=1}^{lfloorfrac{m}{p} floor} [(i,j)=1]$


    $sumlimits_p sumlimits_{d=1}^{min(lfloorfrac{n}{p} floor,lfloorfrac{m}{p} floor)}μ(d)lfloorfrac{n}{pd} floorlfloorfrac{m}{pd} floor$

    设T=pd,枚举T,再枚举T的素因数p,那么d也就等于T/p

    $sumlimits_Tsumlimits_{p|T}μ(frac{T}{p})lfloorfrac{n}{T} floorlfloorfrac{m}{T} floor$

    后面那一块只跟前面的T有关,所以可以提前。

    $sumlimits_Tlfloorfrac{n}{T} floorlfloorfrac{m}{T} floor(sumlimits_{p|T}μ(frac{T}{p}))$

    将后面的预处理出来。
    参考popoqqq的课件,之间枚举一个素数,然后更新p*1,p*2...。

    复杂度:1/1+1/2+1/3+...+1/n=O(logn)

    代码

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 
     6 using namespace std;
     7 
     8 const int N = 10000000;
     9 typedef long long LL;
    10 
    11 bool noprime[N+5];
    12 int pri[N+5],tot,mu[N+5],g[N+5];
    13 
    14 inline int read() {
    15     int x = 0,f = 1;char ch = getchar();
    16     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
    17     for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
    18     return x * f;
    19 }
    20 void init() {
    21     mu[1] = 1; //-
    22     for (int i=2; i<=N; ++i) {
    23         if (!noprime[i]) pri[++tot] = i,mu[i] = -1;
    24         for (int j=1; j<=tot&&i*pri[j]<=N; ++j) {
    25             noprime[i*pri[j]] = true;
    26             if (i % pri[j] == 0) {mu[i*pri[j]] = 0;break;}
    27             mu[i*pri[j]] = -mu[i];
    28         }
    29     }
    30     for (int j=1; j<=tot; ++j) 
    31         for (int i=pri[j]; i<=N; i+=pri[j])
    32             g[i] += mu[i/pri[j]];
    33     for (int i=1; i<=N; ++i) g[i] += g[i-1];
    34 }
    35 void work(int n,int m) {
    36     LL ans = 0;
    37     int c = min(n,m),p;
    38     for (int i=1; i<=c; i=p+1) {
    39         p = min(n/(n/i),m/(m/i));
    40         ans += 1ll*(g[p]-g[i-1])*(n/i)*(m/i);
    41     }
    42     printf("%lld
    ",ans);
    43 }
    44 int main() {
    45     init();
    46     int Case = read();
    47     while (Case--) {
    48         int n = read(),m = read();
    49         work(n,m);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    集合框架
    5.异常
    接口小结
    多态(3)面向对象的三大特征之三
    面向对象编程(1)继承
    第五章博客
    《MySQL数据库》MySQL集群工具mycat安装
    《MySQL数据库》MySQL分区表
    《MySQL数据库》MySQL读写分离(Atlas)
    《Redis内存数据库》Redis数据类型和基本操作
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8847764.html
Copyright © 2020-2023  润新知