您的位置:首页 > 其它

1748. The Most Complex Number/LG的数学计划~~~持续更新ing(反素数求解)

2016-09-06 19:51 453 查看
神奇的反素数, 首先定义

g(x) = x的约数个数

而反素数就是对于任意的0 < j < i 有g(j) < g(i)那么就称i为反素数

那么从这个定义中可以发现的是, 反素数一定是由连续的质数相乘

即对于反素数x一定有x=2^t1*3^t2*5^t3…………..

注意一定要是连续的, 即t1, t2, t3, t4, t5……>0;

好吧说的不清楚, 给百度百科的说明

对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数·
性质一:一个反素数的质因子必然是从2开始连续的质数.
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....


对于这个证明, 自己yy了一下(有不对的话请读者指出, 高中狗):

设x的最小质因数不是2, 那么把其最小的质因数变成2得到新数x’

易知x’一定小于x而约数个数和x相等, 矛盾 得证

同理我们对于第二个性质若i < j && ti >= tj 我们又可以把ti, tj两个指数换一个顺序得到的新数一定比原数小且约数相等, 矛盾, 得证

那么下面是一道反素数的经典例题,

给出T(T∈[1,100]) 每组数据输入一个整数n(n∈[1,10^18])

求小于等于n的 约数最多的 最小数;

典型的模板不多说给出代码(根据上面的性质搜索剪枝得到)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define rep(i, s, t) for(int i = s; i <= t; ++i)

typedef long long ll;
ll prime[30], res = 0, res_cnt, n;

void dfs(ll dep, ll t, ll cnt, ll la) {
if(res_cnt < cnt) res = t, res_cnt = cnt;
if(t < res && res_cnt <= cnt) res = t, res_cnt = cnt;
ll temp = 1;
rep(i, 1, la) {
temp *= prime[dep];
if(n/temp < t) break;//避免乘法爆ll
dfs(dep+1, t*temp, cnt*(i+1), i);
}
}

int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("result.out", "w", stdout);
#endif
int t = 1, _;
prime[t] = 2;
for(ll i = 3; i <= 0x3f3f3f && t <= 30; ++i) {
bool flag = false;
for(int j = 2; (ll)j*j <= i; ++j)
if(i % j == 0) {flag = 1; break;}
if(!flag) prime[++t] = i;
}
cin >> _;
while(_--) {
res_cnt = 0;
res = 0;
scanf("%lld", &n);
dfs(1, 1, 1, 30);
cout << res << " " << res_cnt << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: