zoukankan      html  css  js  c++  java
  • bzoj 2693: jzptab 线性筛积性函数

    2693: jzptab

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 444  Solved: 174
    [Submit][Status][Discuss]

    Description

     

    Input

    一个正整数T表示数据组数

    接下来T行 每行两个正整数 表示N、M

    Output

    T行 每行一个整数 表示第i组数据的结果

     

    Sample Input

    1

    4 5

    Sample Output

    122

    HINT
    T <= 10000

    N, M<=10000000

      重新学习了一下积性函数方式推导莫比乌斯反演系列题目,感觉求sigma(gcd(x,y))、sigma(gcd(x,y)==1)用积性函数的性质推导应该还算是简单,但是求sigma(lcm(x,y))用积性函数就非常恶心了,具体推法详见jzp讲稿:

     传送门:http://wenku.baidu.com/link?url=_glgC9AsqkzOGXSe66vrbLWwf9mr_HZujxaAszME0pCbVtRdcTyhqODy801-tgQdoArjJYYwQGwpQ7E4mdA61OsRYO3qciEfusRQ51JPUCy

      这道题是bzoj 2154《 Crash的数字表格》的多组询问版,如果我没记错的话,那道题我用的是O(n)求sigma(lcm(x,y)),但是jzp讲的神奇的方法可以O(n)预处理,O(sqrt(n))询问。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define MAXP 10010000
    #define MAXN 10010000
    #define MOD 100000009
    typedef long long qword;
    bool pflag[MAXP];
    int prime[MAXP],topp=-1;
    int phi[MAXP];
    int gg[MAXP];
    qword gs[MAXP];
    int mu[MAXP];
    void init()
    {
            phi[1]=1;
            gg[1]=1;
            mu[1]=1;
            for (int i=2;i<MAXP;i++)
            {
                    if (!pflag[i])
                    {
                            prime[++topp]=i;
                            phi[i]=i-1;
                            gg[i]=1-i;
                            mu[i]=-1;
                    }
                    for (int j=0;j<=topp && i*prime[j]<MAXP;j++)
                    {
                            pflag[i*prime[j]]=true;
                            if (i%prime[j]==0)
                            {
                                    phi[i*prime[j]]=phi[i]*prime[j];
                                    gg[i*prime[j]]=gg[i];
                                    mu[i*prime[j]]=0;
                                    break;
                            }
                            phi[i*prime[j]]=phi[i]*(prime[j]-1);
                            gg[i*prime[j]]=gg[i]*(1-prime[j]);
                            mu[i*prime[j]]=-mu[i];
                    }
            }
            for (int i=1;i<MAXP;i++)
                    gs[i]=(gs[i-1]+(qword)gg[i]*i)%MOD;
            return ;
    }
    qword solve(int n,int m)
    {
            qword res=0;
            int l=1;
            for (int i=1;i<=min(n,m);i=l)
            {
                    l=min(n/(n/i),m/(m/i))+1;
                    res=(res+((qword)(n/i)*(n/i+1)/2%MOD)%MOD*((qword)(m/i)*(m/i+1)/2%MOD)%MOD*(gs[l-1]-gs[i-1])%MOD)%MOD;
            }
            res=(res+MOD)%MOD;
            return res;
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int n,m;
            int nn;
            init();
            scanf("%d",&nn);
            while (nn--)
            {
                    scanf("%d%d",&n,&m);
                    printf("%lld
    ",solve(n,m));
            }
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Linux常用命令(文件常用命令)
    Spring中的核心思想
    AOP中重要概念
    Spring框架中2种生成代理对象的方法
    python模块详解 | psutil
    Linux学习笔记 | 常见错误之无法获得锁
    python学习笔记 | 列表去重
    CentOS | python3.7安装指南
    selenium爬虫 | 爬取疫情实时动态(二)
    selenium爬虫 | 爬取疫情实时动态
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4340129.html
Copyright © 2011-2022 走看看