Aladdin and the Flying Carpet LightOJ - 1341(唯一分解 + 素数打表)

Aladdin and the Flying Carpet LightOJ - 1341

题意:

现在有一个矩形, 非正方形
给你一个面积a,最小边的下限是b。

有多少个矩形

思路:

  1. 首先可以把a进行 根据素因子进行唯一分解。(优化,可以先打表,之后再质因数分解
  2. 那么a的因子数是( n u m 1 num_1 num1+1)( n u m 2 num_2 num2+1)。。。( n u m n num_n numn+1).
  3. 在不考虑b的情况下 ans = 上式/2(且是向下取整,因为题目不包含正方形的情况)
  4. 对于一些spj 要特判。(因为b可能大于1e6).

反思

特判没有做好qwq。。。

AC

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#define sz(a) (int)a.size()
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i =(x); i<(y); i++)
#define pb push_back
using namespace std;
typedef long long ll;
vector<ll> prime, prime_num;
int cnt = 0;
const int maxn = 1e6+10;
int vis[maxn];
vector<ll> prime_orl;
void table(){
    for(int i = 2; i < maxn; i++){
        if(!vis[i]){
            prime_orl.pb(i);
            for(int j = 2*i; j<maxn; j += i)vis[j] = 1;
        }
    }
}
void divide(ll x){
    prime.clear(); prime_num.clear();
    if(x==1)return ;
    for(ll i = 0; i<sz(prime_orl) && prime_orl[i]*prime_orl[i] <= x ; i++){
        ll pri = prime_orl[i];
        if(x%pri == 0){
            prime.pb(pri);
            cnt = 0;
            while(x%pri == 0){
                x /= pri;
                cnt++;
            }
            prime_num.pb(cnt);
        }
    }
    if(x>1){prime.pb(x); prime_num.pb(1);}
    return ;
}
int main()
{
   // ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int tt, kase=0; scanf("%d", &tt);//cin>>tt;
    table();
    while(tt--){
        ll a, b;
        scanf("%lld%lld", &a, &b);//cin>>a>>b;
        if(b>=sqrt(a)){
            printf("Case %d: %lld\n", ++kase, 0);
            continue;
        }
        ll ans = 1;
        divide(a);
        fori(i,0,sz(prime_num))ans *= (prime_num[i] + 1);
        ans /= 2;
        for(ll i=1; i<b; i++)if(a%i==0)ans--;
        if(a == 1)ans = 0;
        printf("Case %d: %lld\n", ++kase, ans);
       // cout<<ans<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值