• bzoj:3994:vijos1949: [SDOI2015]约数个数和


    Description

     设d(x)为x的约数个数,给定N、M,求  
     

     

    Input

    输入文件包含多组测试数据。

    第一行,一个整数T,表示测试数据的组数。
    接下来的T行,每行两个整数N、M。
     

    Output

     T行,每行一个整数,表示你所求的答案。

     

    Sample Input

    2
    7 4
    5 6

    Sample Output

    110
    121

    HINT

     1<=N, M<=50000


    1<=T<=50000
     
     
    数论……终于还是的在神犇博客的帮助下才写得出……T_T……
    最后推出一个式子ans=sigma(miu(i)*f(n/i)*f(m/i)),其中f(m/i)为d数组的前缀和……还有个优化是把n/i卡成数段再加起来……
     
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int t,n,m,p[10001],u[50001],s[50001],f[50001],num=0,o,an[22],xn,xm;
    long long ans;
    bool bo[50001];
    char ch;
    inline int min(int x,int y){return x<y?x:y;}
    inline int read(){
        o=0;ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') o=o*10+ch-48, ch=getchar();
        return o;
    }
    int main(){
        scanf("%d",&t);
        u[1]=1;s[1]=1;
        register int i,j;
        for (i=2;i<=50000;i++){
            if (!bo[i]) p[num++]=i,u[i]=-1,s[i]=2,f[i]=1;
            for (j=0;j<num;j++){
                o=i*p[j];
                if (o>50000) break;
                bo[o]=1;
                if (i%p[j]) u[o]=-u[i],s[o]=s[i]*2,f[o]=1;else{
                    u[o]=0;
                    s[o]=s[i]/(f[i]+1)*(f[i]+2);
                    f[o]=f[i]+1;
                }
            }
            s[i]+=s[i-1];u[i]+=u[i-1];
        }
        while(t--){
            n=read();m=read();
            if (n>m) swap(n,m);
            ans=0;
            for (i=1;i<=n;i=j+1) xn=n/i,xm=m/i,j=min(n/xn,m/xm),ans+=((long long)((u[j]-u[i-1])*s[xn])*s[xm]);
            printf("%lld
    ",ans);
        }
    }
     
  • 相关阅读:
    SQL SERVER导入Excel csv
    微信付款码扫码枪支付
    idftp
    不正常地定义参数对象。提供了不一致或不完整的信息
    sql 日志文件截断收缩
    sql server 新语法 收藏
    SQL SERVER 2019新功能
    SQL SERVER 死锁
    rad 10.2
    TXMLDocument 创建空值节点不要缩写
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5085640.html
Copyright © 2020-2023  润新知