C. Orac and LCM
思路
题目非常简单,就是求
对于包含 的项有,
由于每一项都包含 ,所以整体的
同样的其最后的 就是这 项的 的共同的 ,通样的对于所有的 我们可以通过对原数组从后开始求 ,求得。
正确代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
ll f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f * x;
}
const int N = 1e5 + 10;
ll a[N], b[N];
int n;
ll gcd(ll a, ll b) {
return b ? gcd(b, a % b) : a;
}
ll lcm(ll a, ll b) {
return a * b / gcd(a, b);
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
n = read();
for(int i = 1; i <= n; i++)
a[i] = read();
for(int i = n; i >= 1; i--) b[i] = gcd(b[i + 1], a[i]);
ll ans = 0;
for(int i = 1; i <= n; i++)
ans = gcd(ans, lcm(a[i], b[i + 1]));
printf("%lld\n", ans);
return 0;
}
一个不会优化的代码
大概思路就是只有当一个质因子在最少n - 1个数中出现过,其对整体的 才有贡献,所以我们只需要统计这些质因子出现的次数,一个质因子出现了 次,即是他的最小次方的出现项对整体有贡献,如果一个数出现了 次,即是他的次二小次方项对整体有贡献。
但是这个代码的复杂度过高了,优化不出来
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int prime[N], n, cnt, flag[N];
vector<ll> num[N];
bool st[N];
void init() {
st[0] = st[1] = true;
for(int i = 2; i < N; i++) {
if(!st[i]) prime[cnt++] = i;
for(int j = 0; j < cnt && prime[j] * i < N; j++) {
st[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
int main() {
// freopen("in.txt", "r", stdin);
scanf("%d", &n);
init();
int t;
for(int i = 0; i < n; i++) {
scanf("%d", &t);
for(int j = 0; prime[j] <= t; j++) {
ll sum = 1;
while(t % prime[j] == 0) {
t /= prime[j];
sum *= prime[j];
}
if(sum != 1) {
flag[j]++;
num[j].push_back(sum);
}
}
}
ll ans = 1;
for(int i = 0; i < cnt; i++) {
if(flag[i] == n - 1) {
sort(num[i].begin(), num[i].end());
ans *= num[i][0];
}
if(flag[i] == n) {
sort(num[i].begin(), num[i].end());
ans *= num[i][1];
}
}
printf("%lld\n", ans);
return 0;
}