1. 程式人生 > >洛谷 P1221 最多因子數(搜尋)

洛谷 P1221 最多因子數(搜尋)

題目描述

數學家們喜歡各種型別的有奇怪特性的數。例如,他們認為945是一個有趣的數,因為它是第一個所有約數之和大於本身的奇數。

為了幫助他們尋找有趣的數,你將寫一個程式掃描一定範圍內的數,並確定在此範圍內約數個數最多的那個數。不幸的是,這個數和給定的範圍的都比較大,用簡單的方法尋找可能需要較多的執行時間。所以請確定你的演算法能在幾秒內完成最大範圍內的掃描。

輸入輸出格式

輸入格式:

只有一行,給出掃描的範圍,由下界L和上界U確定。滿足2≤L≤U≤1000000000。

輸出格式:

對於給定的範圍,輸出該範圍內約數個數D最多的數P。若有多個,則輸出最小的那個。請輸出“Between L and U,P has a maximum of D divisors.”,其中L,U,P和D的含義同前面所述。

輸入輸出樣例

輸入樣例#1: 複製

1000 2000

輸出樣例#1: 複製

Between 1000 and 2000, 1680 has a maximum of 40 divisors.

PS:其實就是找因子數最多的數,根據一個數都能被多個質因子分解,例如 p=a1^p1+a2^p2+……+an^pn.ai表示質數,pi表示該數字內有pi個ai,他的因子數sum就是sum=(p1+1)*(p2+1)*……*(pn+1)。除了131074,他有個質因子大於100,其他所有數的因子都小於100,所以只需要特判131074,其他都直接用dfs質因子跑質因子數目就行了。  

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=5e5+10;
const int mod=1e9+7;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;
ll l,r,ans,sum;
ll s[30]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,91,97},p[30];
void check(ll s)
{
    ll res=1;
    for(int i=1;i<=26;i++)
        res*=(p[i]+1);
    if(res>sum)
        sum=res,ans=s;
    else if(res==sum)
        ans=min(s,ans);
}
void dfs(ll sum,int st)
{
    if(sum>r)
        return ;
    else if(l<=sum&&sum<=r)
        check(sum);
    for(int i=st;i<=26;i++)
    {
        p[i]++;
        dfs(sum*s[i],i);
        p[i]--;
    }
}
int main()
{
    cin>>l>>r;
    if(l==r&&l==131074)
        printf("Between 131074 and 131074, 131074 has a maximum of 4 divisors.\n");
    else
    {
        dfs(1,1);
        printf("Between %lld and %lld, %lld has a maximum of %lld divisors.\n",l,r,ans,sum);
    }
    return 0;
}