51Nod-1434-區間LCM
阿新 • • 發佈:2019-01-27
描述
題解
這裡我們可以肯定的是M一定不大於2 * N
,這裡我們只需要考慮所有質因子最高階對應的數字即可,求得這些數字中最大的,結果一定是這個數的二倍(這裡的二倍和前邊的2 * N
道理是一樣的)。為啥只用考慮最高階呢?因為低階的一定都能夠由多個數字提供因子組成,所以可以不用考慮(One)。
不管用什麼辦法實現,貌似都需要線性篩,篩選出小於N的所有素數,不同的就是ans
的求法,花樣很多,但是都是和最高階有關(Two)。
程式碼
One:
#include <stdio.h>
#define MAXN 1000009
#define MAXP 300000
#define max(a, b) ((a) > (b) ? (a) : (b))
int prime[MAXN];
int p[MAXP];
int main()
{
int k = 0;
for (int i = 2; i < MAXN; i++)
{
if (!prime[i])
{
p[k++] = i;
for (int j = 2 * i; j < MAXN; j += i)
{
prime[j] = 1;
}
}
}
int T;
scanf("%d ", &T);
while (T--)
{
int N, g = 1;
scanf("%d", &N);
for (int i = 0; p[i] <= N; i++)
{
for (int j = p[i]; j <= N; j *= p[i])
{
g = max(g, j);
}
}
printf("%d\n", g * 2);
}
return 0;
}
Two:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define rep(i, s, t) for (int i = s; i <= t; i++)
#define dwn(i, s, t) for (int i = s; i >= t; i--)
#define clr(x, c) memset(x, c, sizeof(x))
#define ll long long
using namespace std;
const int MAXN = 1e6 + 5;
int prime[MAXN << 3];
bool vis[MAXN + 1];
int main()
{
int cnt = 0, tp;
rep(i, 2, MAXN)
{
if (!vis[i])
{
prime[++cnt] = i;
}
rep(j, 1, cnt)
{
tp = prime[j];
if ((ll)tp * i > MAXN)
{
break;
}
vis[tp * i] = 1;
if (i % tp == 0)
{
break;
}
}
}
int T, u, v;
scanf("%d", &T);
while (T--)
{
int n;
scanf("%d", &n);
int ans = n;
if (n == 1)
{
printf("2\n");
continue;
}
rep(i, 1, cnt)
{
if (prime[i] > n)
{
break;
}
tp = 1;
u = (int)(log(n) / log(prime[i]));
v = (int)pow(prime[i], u);
for (int j = 2; ; ++j)
{
if (v * j > n)
{
v *= j;
break;
}
}
ans = max(ans, v);
}
printf("%d\n", ans);
}
return 0;
}