loj1236(数学)

传送门:Pairs Forming LCM 

题意:题意:问符合 lcm(i,j)=n (1<=i<=j<=n,1<=n<=10^14) 的 (i,j) 有多少对。

分析:求素数分解式,若xi是第i个素数的幂,那么对于这两个数中有一个的幂一定是xi,另一个随意,那么对于第i的素数的分配方案有(2*xi+1)种(即假设第一个数的幂是xi,另一个数的幂可以为0~xi共xi+1种;另一方面假设第二个数是xi,同理第一个数的幂的选择有xi+1种,这里排除幂都是xi的情况,对于某个素数pi,这两个数的幂的选择方案有2*xi+1种)。那么对于所有素数,共有∏(2*xi+1)种分配方案,由于要排除(a,b),(b,a)这种情况,在之前的计算中除了两个数都是n这种情况都有重复,答案则应该是(∏(2*xi+1)+1)/2

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <limits.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-6
#define N 10000000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PII pair<int,int>
using namespace std;
inline LL read()
{
    char ch=getchar();LL x=0,f=1;
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
bool vis[N+5];
int prime[670000],tot;
void init()
{
    memset(vis,false,sizeof(vis));
    tot=0;
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])
        {
            prime[tot++]=i;
        }
        for(int j=0;j<tot&&i*prime[j]<=N;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)break;
        }
    }
}

int main()
{
    LL n;
    int T,cas=1;
    init();
    T=read();
    while(T--)
    {
       n=read();
       LL ans=1;
       for(int i=0;i<tot&&(LL)prime[i]*prime[i]<=n;i++)
       {
           if(n%prime[i]==0)
           {
               LL x=0;
               while(n%prime[i]==0)
               {
                   x++;n/=prime[i];
               }
               ans*=(x*2+1);
           }
       }
       if(n>1)ans*=3;
       printf("Case %d: %lld
",cas++,(ans+1)/2);
    }
}
View Code
原文地址:https://www.cnblogs.com/lienus/p/4298657.html