题目链接:https://codeforces.com/contest/1834/problem/E
题意:
有长度为n的序列,问最小的正整数 x ,对于任意连续的子区间,区间的数的最小公倍数 都不等于 x;
分析:
首先来分析一下答案的范围是多少;
我们可以知道,对于长度 为n 的序列,前 n + 1个素数里面,他至少有一个是不会出现的;
然后我们拿筛子跑一遍,发现第 3e5 + 1的素数是 T = 4256233;
我们固定右端点,我们发现,如果LCM要增加,那么他一定至少是 乘 2的;
所以左边出现的本质不同的LCM 不会多于 log(T)个;
故我们可以暴力来跑,用set来维护左边本质不同的LCM;
时间复杂度:O(n * log(T)* log(T));
代码:
#include<bits/stdc++.h> #define int long long const int up = 4256233; int GCD(int a, int b) { return b ? GCD(b, a % b) : a; } int LCM(int a, int b) { return a * b / GCD(a, b); } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int T; std::cin >> T; while (T--) { int n; std::cin >> n; std::vector<int> a(n + 1, 0); for (int i = 1; i <= n; ++i)std::cin >> a[i]; std::set<int> ans, now, lst; for (int i = 1; i <= n; ++i) { now.clear(); for (auto x: lst) { int y = LCM(x, a[i]); if (y >= up)continue; now.insert(y); } now.insert(a[i]); lst.clear(); for (auto x: now)lst.insert(x), ans.insert(x); } int mex = 1; for (auto x: ans)if (mex == x)mex++; else break; std::cout << mex << "\n"; } return 0; }
哈哈哈,暴力,水题(bushi:)