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

[SDOI2015]约数个数和

时间:2018-10-05 00:01:14      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:type   blog   tin   main   return   ret   names   div   .net   

https://blog.csdn.net/ab_ever/article/details/76737617

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=50000+5;
int n,m,t;
ll g[N];
int u[N],su[N];
bool vis[N];
int pri[N],tot;
void sieve(){
    u[1]=1;
    for(int i=2;i<=N-3;i++){
        if(!vis[i]){
            pri[++tot]=i;
            u[i]=-1;
        }
        for(int j=1;j<=tot;j++){
            if(pri[j]*i>N-3) break;
            vis[pri[j]*i]=1;
            if(i%pri[j]==0){
                u[pri[j]*i]=0;
                break;
            }
            else u[pri[j]*i]=-u[i];
        }
    }
}
ll p[N];//wrk for g
void pre(){
    for(int i=1;i<=N-3;i++)su[i]=su[i-1]+u[i];
    for(int i=1;i<=N-3;i++){
        for(int j=i;j<=N-3;j+=i){
            p[j]++;
        }
    }
    for(int i=1;i<=N-3;i++) g[i]=g[i-1]+p[i];
}
int main(){
    sieve();
    pre();
    cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        int ptr=1;
        ll ans=0;
        for(;ptr*ptr<=max(n,m)&&ptr<=min(n,m);ptr++){
            ans+=u[ptr]*g[n/ptr]*g[m/ptr];
        }
        if(ptr>min(n,m)) {
            printf("%lld\n",ans);
            continue;
        }
        if(n>m) swap(n,m);
        int rn=n/ptr,rm=m/ptr;
        int pn,pm;
        while(1){
            pn=n/rn,pm=m/rm;
            int tmp=min(pn,pm);
            ans+=(su[tmp]-su[ptr-1])*g[rn]*g[rm];
            if(tmp==n) break;
            ptr=tmp+1;
            rn=n/ptr,rm=m/ptr;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

/*
   Author: *Miracle*
   Date: 2018/10/4 22:08:25
*/

 

[SDOI2015]约数个数和

标签:type   blog   tin   main   return   ret   names   div   .net   

原文地址:https://www.cnblogs.com/Miracevin/p/9743750.html

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