Light OJ 1341 Aladdin and the Flying Carpet(算数基本定理)

来源:互联网 发布:淘宝原单包店铺推荐 编辑:程序博客网 时间:2024/06/08 09:40

题目:https://vjudge.net/contest/70017#problem/C

题意:给出a,b求所有(c,d)满足c*d=a,且c>=b,d>=b的二元组个数。

思路:这题一开始肯定会想到最朴素的求解因子个数的算法,但是a较大,会超时,于是想到算数基本定理,预先用素数筛法求出一百万以内(根号10^12)的所有素数,根据算数基本定理求出a的所有因子个数,再折半减掉所有小于b的因子,结果即为所求。

代码:

#include<iostream>#include<algorithm>#include<cstring>using namespace std;#define LL long longconst int maxn = 1e6 + 10;int num[maxn],prime[maxn/10];LL a,b;int cnt=0;void getPrime(){///素数筛法    memset(num,0,sizeof(num));    for(int i=2;i*i<=maxn;i++)        if(!num[i])            for(int j=i*i;j<=maxn;j+=i)                num[j]=1;    for(int i=2;i<=maxn;i++)        if(!num[i])            prime[cnt++]=i;}int slove(){    LL tmp=a;    int ans=1;    if(a/b<=b) return 0;///注意先考虑特殊情况    for(int i=0;i<cnt&&prime[i]*prime[i]<=a;i++){        int s=0;        while(a%prime[i]==0){            s++;            a/=prime[i];        }        ans*=(s+1);        ///if(a==1) break;    }    if(a>1) ans*=2;    ans/=2;    for(LL i=1;i<b;i++){        if(tmp%i==0)            ans--;    }    return ans;}int main(){    getPrime();    int t,cas=1;    cin>>t;    while(t--){        cin>>a>>b;        cout<<"Case "<<cas++<<": "<<slove()<<endl;    }}
要搞清代码的每一个细节实在不简单啊!

阅读全文
0 0