Aladdin and the Flying Carpet LightOJ 1341 唯一分解定理

 

 

 题意:给出a,b,问有多少种长方形满足面积为a,最短边>=b?

首先简单讲一下唯一分解定理。

唯一分解定理:任何一个自然数N,都可以满足:,pi是质数。

 

 

 

且N的正因子个数为(1+a1)*(1+a2)*(1+a3)*.......*(1+an)。

看了网络上很多人写的题解,普遍的做法是先找出N的所有正因子n,(n/2)就是在不考虑最短边>=b时所有存在的长方形,现在考虑最短边>=b,只需要减去所有能整除a且小于b的因子即可。

具体写法:

1.先预处理素数

2.用唯一分解定理求出N的所有因子

3.减去使得最短边<b的因子对

AC code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool u[1000005];
ll su[1000005];
ll a,b,tmp,num,sum;
void olas()
{
    num=1;
    memset(u,true,sizeof(u));
    for(ll i=2; i<=1000000; i++)
    {
        if(u[i])    su[num++]=i;
        for(ll j=1; j<num; j++)
        {
            if(i*su[j]>1000000)    break;
            u[i*su[j]]=false;
            if(i%su[j]==0)    break;
        }
    }
}
void cal()
{
    sum=1;
    for(ll i=1; i<num&&su[i]<=sqrt(tmp); i++)
    {
        ll cc=0;
        while(tmp%su[i]==0)
        {
            cc++;
            tmp/=su[i];
        }
        sum*=(1+cc);
    }
    if(tmp>1)    sum*=2;
}
int main()
{
    //freopen("input.txt","r",stdin);
    olas();
    ll T,kase=1;
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld",&a,&b);
        if(a<b*b)    printf("Case %lld: 0\n",kase++);
        else
        {
            tmp=a;
            cal();
            sum/=2;
            for(ll i=1; i<b; i++)
            {
                if(a%i==0)    sum--;
            }
            printf("Case %lld: %lld\n",kase++,sum);
        }
    }
    return 0; 
}
View Code

存疑:

虽然说按照以上写法可以AC,考虑到有T可以取到4000,b可以取到1000000,假设有测试数据如下:

T = 4000

case 1:a=10^12 ,b=10^6

case 2:a=10^12 ,b=10^6-1

case 3:a=10^12 ,b=10^6-2

.......

case 4000:a=10^12,b=10^6-3999

这样一来由于每次都遍历了1->b,真实时间复杂度>O(4000*10^6)在3000ms内必然TLE。

但是本题不存在这样的测试数据。。。。。。。所以可以直接水过。。

posted on 2019-09-03 09:40  Caution_X  阅读(158)  评论(0编辑  收藏  举报

导航