码迷,mamicode.com
首页 > 其他好文 > 详细

SDOI2015 约数个数和

时间:2015-04-22 00:05:20      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

Description

技术分享
 

Input

输入文件包含多组测试数据。
第一行,一个整数T,表示测试数据的组数。
接下来的T行,每行两个整数N、M。

Output

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

Sample Input

2
7 4
5 6

Sample Output

110
121
 

Data Constraint

技术分享
 

解法:莫比乌斯反演,话说SD去年好像也出了题反演题

贴大神的blog题解

http://blog.codebursts.com/bzoj3994/

 

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;
typedef long long ll;

ll num[50011],mu[50011],ans;
int pri[50011],np[50011];
bool p[50011];
int dt,tj,i,j,n,m;

void prepare()
{
    ll tz;
    int i,j,lim,tot;
    lim=50000;
    tot=0;
    memset(p,true,sizeof(p));
    num[1]=1;
    mu[1]=1;
    for(i=2;i<=lim;i++){
        if(p[i]){
            pri[++tot]=i;
            num[i]=2;
            np[i]=1;
            mu[i]=-1;
        }
        for(j=1;j<=tot;j++){
            tz=(ll)pri[j]*i;
            if(tz>lim)break;            
            p[pri[j]*i]=false;
            if(i%pri[j]==0){
                np[pri[j]*i]=np[i]+1;
                num[pri[j]*i]=num[i]/(np[i]+1)*(np[i]+2);
                mu[pri[j]*i]=0;
                break;
            }
            np[pri[j]*i]=1;
            num[pri[j]*i]=num[i]*2;
            mu[pri[j]*i]=-mu[i];
        }
    }
    for(i=1;i<=lim;i++){
        num[i]+=num[i-1];
        mu[i]+=mu[i-1];
    }
}

int main()
{
    scanf("%d",&dt);
    prepare();
    for(tj=1;tj<=dt;tj++){
        scanf("%d%d",&n,&m);
        if(n>m)swap(n,m);
        ans=0;
        for(i=1,j;i<=n;i=j+1){
            j=min(n/(n/i),m/(m/i));
            ans+=1ll*num[n/i]*num[m/i]*(mu[j]-mu[i-1]);
        }
        printf("%lld\n",ans);
    }
}

 

SDOI2015 约数个数和

标签:

原文地址:http://www.cnblogs.com/applejxt/p/4445627.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!