CF1436E Complicated Computations 题解
题目链接:CF 或者 洛谷
关于
来讲讲常见的两种解决方案,首先回到题目所问,如果我们暴力地询问:
-
,则该序列不包括 ,否则可以拓展为 。 -
关于 单调不降,即元素个数越多, 越可能变大。 -
不包含 ,则 ,这个很显而易见。
其实这三条性质告诉了我们一种方式:
如果构造出
为啥要选择两个
解法一
普通莫队+值域分块平衡复杂度
建议先学习:值域分块系统级教学
对于莫队怎么求区间
那么这样的复杂度是,插入和删除是
所以上述复杂度并不合理,我们需要
参照代码
#include <bits/stdc++.h> // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") // #define isPbdsFile #ifdef isPbdsFile #include <bits/extc++.h> #else #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/rope> #endif using namespace std; using namespace __gnu_cxx; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> tii; typedef tuple<ll, ll, ll> tll; typedef unsigned int ui; typedef unsigned long long ull; typedef __int128 i128; #define hash1 unordered_map #define hash2 gp_hash_table #define hash3 cc_hash_table #define stdHeap std::priority_queue #define pbdsHeap __gnu_pbds::priority_queue #define sortArr(a, n) sort(a+1,a+n+1) #define all(v) v.begin(),v.end() #define yes cout<<"YES" #define no cout<<"NO" #define Spider ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); #define MyFile freopen("..\\input.txt", "r", stdin),freopen("..\\output.txt", "w", stdout); #define forn(i, a, b) for(int i = a; i <= b; i++) #define forv(i, a, b) for(int i=a;i>=b;i--) #define ls(x) (x<<1) #define rs(x) (x<<1|1) #define endl '\n' //用于Miller-Rabin [[maybe_unused]] static int Prime_Number[13] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; template <typename T> int disc(T* a, int n) { return unique(a + 1, a + n + 1) - (a + 1); } template <typename T> T lowBit(T x) { return x & -x; } template <typename T> T Rand(T l, T r) { static mt19937 Rand(time(nullptr)); uniform_int_distribution<T> dis(l, r); return dis(Rand); } template <typename T1, typename T2> T1 modt(T1 a, T2 b) { return (a % b + b) % b; } template <typename T1, typename T2, typename T3> T1 qPow(T1 a, T2 b, T3 c) { a %= c; T1 ans = 1; for (; b; b >>= 1, (a *= a) %= c)if (b & 1)(ans *= a) %= c; return modt(ans, c); } template <typename T> void read(T& x) { x = 0; T sign = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-')sign = -1; ch = getchar(); } while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } x *= sign; } template <typename T, typename... U> void read(T& x, U&... y) { read(x); read(y...); } template <typename T> void write(T x) { if (typeid(x) == typeid(char))return; if (x < 0)x = -x, putchar('-'); if (x > 9)write(x / 10); putchar(x % 10 ^ 48); } template <typename C, typename T, typename... U> void write(C c, T x, U... y) { write(x), putchar(c); write(c, y...); } template <typename T11, typename T22, typename T33> struct T3 { T11 one; T22 tow; T33 three; bool operator<(const T3 other) const { if (one == other.one) { if (tow == other.tow)return three < other.three; return tow < other.tow; } return one < other.one; } T3() { one = tow = three = 0; } T3(T11 one, T22 tow, T33 three) : one(one), tow(tow), three(three) { } }; template <typename T1, typename T2> void uMax(T1& x, T2 y) { if (x < y)x = y; } template <typename T1, typename T2> void uMin(T1& x, T2 y) { if (x > y)x = y; } constexpr int N = 2e5 + 10; int pos[N]; struct Mo { int l, r; bool operator<(const Mo& other) const { return pos[l] ^ pos[other.l] ? pos[l] < pos[other.l] : pos[l] & 1 ? r < other.r : r > other.r; } } node[N]; int n, q; vector<int> t[N]; int a[N]; bool vis[N]; int val[N], valPos[N]; int siz, cnt, s[N], e[N]; int Cnt[N]; inline void update(const int x, const int v) { const int id = pos[x]; val[id] += v, valPos[x] += v; } inline void add(const int x) { if (Cnt[x]++ == 0)update(x, 1); } inline void del(const int x) { if (--Cnt[x] == 0)update(x, -1); } inline int queryMex() { int id = 1; while (id <= cnt and val[id] == e[id] - s[id] + 1)id++; if (id > cnt)return n + 1; int ans = s[id]; while (ans <= e[id] and valPos[ans])ans++; return ans; } inline void solve() { cin >> n; siz = sqrt(n); cnt = (n + siz - 1) / siz; forn(i, 1, n)cin >> a[i], t[a[i]].push_back(i), pos[i] = (i - 1) / siz + 1; forn(i, 1, cnt)s[i] = (i - 1) * siz + 1, e[i] = i * siz; e[cnt] = n; forn(i, 1, n+1) { int l = 1; for (const auto r : t[i]) { if (l == r) { l = r + 1; continue; } node[++q] = Mo(l, r - 1), l = r + 1; } if (l < n)node[++q] = Mo(l, n); } sortArr(node, q); int l = 1, r = 0; forn(i, 1, q) { const auto [L,R] = node[i]; while (l < L)del(a[l++]); while (l > L)add(a[--l]); while (r < R)add(a[++r]); while (r > R)del(a[r--]); vis[queryMex()] = true; } int mex = 1; while (vis[mex])mex++; cout << mex; } signed int main() { // MyFile Spider //------------------------------------------------------ // clock_t start = clock(); int test = 1; // read(test); // cin >> test; forn(i, 1, test)solve(); // while (cin >> n, n)solve(); // while (cin >> test)solve(); // clock_t end = clock(); // cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; }
解法二
回滚莫队
太经典了,区间
如图所示,如果
参照代码
#include <bits/stdc++.h> // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") // #define isPbdsFile #ifdef isPbdsFile #include <bits/extc++.h> #else #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/rope> #endif using namespace std; using namespace __gnu_cxx; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> tii; typedef tuple<ll, ll, ll> tll; typedef unsigned int ui; typedef unsigned long long ull; typedef __int128 i128; #define hash1 unordered_map #define hash2 gp_hash_table #define hash3 cc_hash_table #define stdHeap std::priority_queue #define pbdsHeap __gnu_pbds::priority_queue #define sortArr(a, n) sort(a+1,a+n+1) #define all(v) v.begin(),v.end() #define yes cout<<"YES" #define no cout<<"NO" #define Spider ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); #define MyFile freopen("..\\input.txt", "r", stdin),freopen("..\\output.txt", "w", stdout); #define forn(i, a, b) for(int i = a; i <= b; i++) #define forv(i, a, b) for(int i=a;i>=b;i--) #define ls(x) (x<<1) #define rs(x) (x<<1|1) #define endl '\n' //用于Miller-Rabin [[maybe_unused]] static int Prime_Number[13] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; template <typename T> int disc(T* a, int n) { return unique(a + 1, a + n + 1) - (a + 1); } template <typename T> T lowBit(T x) { return x & -x; } template <typename T> T Rand(T l, T r) { static mt19937 Rand(time(nullptr)); uniform_int_distribution<T> dis(l, r); return dis(Rand); } template <typename T1, typename T2> T1 modt(T1 a, T2 b) { return (a % b + b) % b; } template <typename T1, typename T2, typename T3> T1 qPow(T1 a, T2 b, T3 c) { a %= c; T1 ans = 1; for (; b; b >>= 1, (a *= a) %= c)if (b & 1)(ans *= a) %= c; return modt(ans, c); } template <typename T> void read(T& x) { x = 0; T sign = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-')sign = -1; ch = getchar(); } while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } x *= sign; } template <typename T, typename... U> void read(T& x, U&... y) { read(x); read(y...); } template <typename T> void write(T x) { if (typeid(x) == typeid(char))return; if (x < 0)x = -x, putchar('-'); if (x > 9)write(x / 10); putchar(x % 10 ^ 48); } template <typename C, typename T, typename... U> void write(C c, T x, U... y) { write(x), putchar(c); write(c, y...); } template <typename T11, typename T22, typename T33> struct T3 { T11 one; T22 tow; T33 three; bool operator<(const T3 other) const { if (one == other.one) { if (tow == other.tow)return three < other.three; return tow < other.tow; } return one < other.one; } T3() { one = tow = three = 0; } T3(T11 one, T22 tow, T33 three) : one(one), tow(tow), three(three) { } }; template <typename T1, typename T2> void uMax(T1& x, T2 y) { if (x < y)x = y; } template <typename T1, typename T2> void uMin(T1& x, T2 y) { if (x > y)x = y; } constexpr int N = 2e5 + 10; int pos[N]; struct Mo { int l, r; bool operator<(const Mo& other) const { return pos[l] ^ pos[other.l] ? pos[l] < pos[other.l] : r > other.r; } } node[N]; int n, q; vector<int> t[N]; int a[N]; bool vis[N]; int curr = 1; int siz, cnt, s[N], e[N]; int Cnt[N]; stack<int> back; inline void del(const int x, const bool isBack = false) { if (--Cnt[x] == 0 and x < curr)curr = x; if (isBack)back.push(x); } int tmp[N]; inline void solve() { cin >> n; siz = sqrt(n); cnt = (n + siz - 1) / siz; forn(i, 1, n)cin >> a[i], t[a[i]].push_back(i), pos[i] = (i - 1) / siz + 1; forn(i, 1, cnt)s[i] = (i - 1) * siz + 1, e[i] = i * siz; e[cnt] = n; forn(i, 1, n+1) { int l = 1; for (const auto r : t[i]) { if (l == r) { l = r + 1; continue; } node[++q] = Mo(l, r - 1), l = r + 1; } if (l < n)node[++q] = Mo(l, n); } sortArr(node, q); int l = 1, r = 0, last = 0; forn(i, 1, q) { const auto [L,R] = node[i]; if (pos[L] == pos[R]) { forn(i, L, R)tmp[a[i]]++; int mex = 1; while (tmp[mex])mex++; vis[mex] = true; forn(i, L, R)tmp[a[i]]--; continue; } if (pos[L] != last) { last = pos[L]; curr = 1; forn(i, 1, n)Cnt[i] = 0; forn(i, s[pos[L]], n)Cnt[a[i]]++; while (Cnt[curr])curr++; l = s[pos[L]], r = n; } while (r > R)del(a[r--]); const int pre = curr; int tmpL = l; while (tmpL < L)del(a[tmpL++], true); vis[curr] = true; while (!back.empty())Cnt[back.top()]++, back.pop(); curr = pre; } int mex = 1; while (vis[mex])mex++; cout << mex; } signed int main() { // MyFile Spider //------------------------------------------------------ // clock_t start = clock(); int test = 1; // read(test); // cin >> test; forn(i, 1, test)solve(); // while (cin >> n, n)solve(); // while (cin >> test)solve(); // clock_t end = clock(); // cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; }
解法三
在线主席树上二分
关于
对于询问区间
枚举
这个咋解决?我们抽象下:
为每个权值记录
我们维护
对于一堆查询,它们的
参照代码
#include <bits/stdc++.h> // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") // #define isPbdsFile #ifdef isPbdsFile #include <bits/extc++.h> #else #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/rope> #endif using namespace std; using namespace __gnu_cxx; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> tii; typedef tuple<ll, ll, ll> tll; typedef unsigned int ui; typedef unsigned long long ull; typedef __int128 i128; #define hash1 unordered_map #define hash2 gp_hash_table #define hash3 cc_hash_table #define stdHeap std::priority_queue #define pbdsHeap __gnu_pbds::priority_queue #define sortArr(a, n) sort(a+1,a+n+1) #define all(v) v.begin(),v.end() #define yes cout<<"YES" #define no cout<<"NO" #define Spider ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); #define MyFile freopen("..\\input.txt", "r", stdin),freopen("..\\output.txt", "w", stdout); #define forn(i, a, b) for(int i = a; i <= b; i++) #define forv(i, a, b) for(int i=a;i>=b;i--) #define ls(x) (x<<1) #define rs(x) (x<<1|1) #define endl '\n' //用于Miller-Rabin [[maybe_unused]] static int Prime_Number[13] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; template <typename T> int disc(T* a, int n) { return unique(a + 1, a + n + 1) - (a + 1); } template <typename T> T lowBit(T x) { return x & -x; } template <typename T> T Rand(T l, T r) { static mt19937 Rand(time(nullptr)); uniform_int_distribution<T> dis(l, r); return dis(Rand); } template <typename T1, typename T2> T1 modt(T1 a, T2 b) { return (a % b + b) % b; } template <typename T1, typename T2, typename T3> T1 qPow(T1 a, T2 b, T3 c) { a %= c; T1 ans = 1; for (; b; b >>= 1, (a *= a) %= c)if (b & 1)(ans *= a) %= c; return modt(ans, c); } template <typename T> void read(T& x) { x = 0; T sign = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-')sign = -1; ch = getchar(); } while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } x *= sign; } template <typename T, typename... U> void read(T& x, U&... y) { read(x); read(y...); } template <typename T> void write(T x) { if (typeid(x) == typeid(char))return; if (x < 0)x = -x, putchar('-'); if (x > 9)write(x / 10); putchar(x % 10 ^ 48); } template <typename C, typename T, typename... U> void write(C c, T x, U... y) { write(x), putchar(c); write(c, y...); } template <typename T11, typename T22, typename T33> struct T3 { T11 one; T22 tow; T33 three; bool operator<(const T3 other) const { if (one == other.one) { if (tow == other.tow)return three < other.three; return tow < other.tow; } return one < other.one; } T3() { one = tow = three = 0; } T3(T11 one, T22 tow, T33 three) : one(one), tow(tow), three(three) { } }; template <typename T1, typename T2> void uMax(T1& x, T2 y) { if (x < y)x = y; } template <typename T1, typename T2> void uMin(T1& x, T2 y) { if (x > y)x = y; } constexpr int N = 2e5 + 10; int n, q; vector<int> t[N]; int a[N]; bool vis[N]; int cnt; constexpr int INF = 1e9 + 7; struct Node { int mi; int left, right; } node[N << 5]; #define left(x) node[x].left #define right(x) node[x].right #define mi(x) node[x].mi int root[N]; inline void pushUp(const int curr) { mi(curr) = min(mi(left(curr)),mi(right(curr))); } inline void add(const int pre, int& curr, const int pos, const int val, const int l = 1, const int r = n + 2) { node[curr = ++cnt] = node[pre]; const int mid = l + r >> 1; if (l == r) { mi(curr) = val; return; } if (pos <= mid)add(left(pre),left(curr), pos, val, l, mid); else add(right(pre),right(curr), pos, val, mid + 1, r); pushUp(curr); } inline int queryMex(const int curr, const int pos, const int l = 1, const int r = n + 2) { if (l == r)return l; const int mid = l + r >> 1; if (mi(left(curr)) < pos)return queryMex(left(curr), pos, l, mid); return queryMex(right(curr), pos, mid + 1, r); } inline void solve() { cin >> n; forn(i, 1, n)cin >> a[i], t[a[i]].push_back(i); forn(i, 1, n)add(root[i - 1], root[i], a[i], i); forn(i, 1, n+1) { int l = 1; for (const auto r : t[i]) { if (l == r) { l = r + 1; continue; } vis[queryMex(root[r - 1], l)] = true, l = r + 1; } if (l < n)vis[queryMex(root[n], l)] = true; } int mex = 1; while (vis[mex])mex++; cout << mex; } signed int main() { // MyFile Spider //------------------------------------------------------ // clock_t start = clock(); int test = 1; // read(test); // cin >> test; forn(i, 1, test)solve(); // while (cin >> n, n)solve(); // while (cin >> test)solve(); // clock_t end = clock(); // cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; }
第四种解法
离线扫描线询问+线段树上二分
既然本题可以在线做,当然也可以离线做,我们把所有询问挂载在序列扫描线上,直接从
参照代码
#include <bits/stdc++.h> // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") // #define isPbdsFile #ifdef isPbdsFile #include <bits/extc++.h> #else #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/rope> #endif using namespace std; using namespace __gnu_cxx; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> tii; typedef tuple<ll, ll, ll> tll; typedef unsigned int ui; typedef unsigned long long ull; typedef __int128 i128; #define hash1 unordered_map #define hash2 gp_hash_table #define hash3 cc_hash_table #define stdHeap std::priority_queue #define pbdsHeap __gnu_pbds::priority_queue #define sortArr(a, n) sort(a+1,a+n+1) #define all(v) v.begin(),v.end() #define yes cout<<"YES" #define no cout<<"NO" #define Spider ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); #define MyFile freopen("..\\input.txt", "r", stdin),freopen("..\\output.txt", "w", stdout); #define forn(i, a, b) for(int i = a; i <= b; i++) #define forv(i, a, b) for(int i=a;i>=b;i--) #define ls(x) (x<<1) #define rs(x) (x<<1|1) #define endl '\n' //用于Miller-Rabin [[maybe_unused]] static int Prime_Number[13] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; template <typename T> int disc(T* a, int n) { return unique(a + 1, a + n + 1) - (a + 1); } template <typename T> T lowBit(T x) { return x & -x; } template <typename T> T Rand(T l, T r) { static mt19937 Rand(time(nullptr)); uniform_int_distribution<T> dis(l, r); return dis(Rand); } template <typename T1, typename T2> T1 modt(T1 a, T2 b) { return (a % b + b) % b; } template <typename T1, typename T2, typename T3> T1 qPow(T1 a, T2 b, T3 c) { a %= c; T1 ans = 1; for (; b; b >>= 1, (a *= a) %= c)if (b & 1)(ans *= a) %= c; return modt(ans, c); } template <typename T> void read(T& x) { x = 0; T sign = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-')sign = -1; ch = getchar(); } while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } x *= sign; } template <typename T, typename... U> void read(T& x, U&... y) { read(x); read(y...); } template <typename T> void write(T x) { if (typeid(x) == typeid(char))return; if (x < 0)x = -x, putchar('-'); if (x > 9)write(x / 10); putchar(x % 10 ^ 48); } template <typename C, typename T, typename... U> void write(C c, T x, U... y) { write(x), putchar(c); write(c, y...); } template <typename T11, typename T22, typename T33> struct T3 { T11 one; T22 tow; T33 three; bool operator<(const T3 other) const { if (one == other.one) { if (tow == other.tow)return three < other.three; return tow < other.tow; } return one < other.one; } T3() { one = tow = three = 0; } T3(T11 one, T22 tow, T33 three) : one(one), tow(tow), three(three) { } }; template <typename T1, typename T2> void uMax(T1& x, T2 y) { if (x < y)x = y; } template <typename T1, typename T2> void uMin(T1& x, T2 y) { if (x > y)x = y; } constexpr int N = 2e5 + 10; int n, q; vector<int> t[N]; int a[N]; bool vis[N]; int cnt; constexpr int INF = 1e9 + 7; struct Node { int mi; } node[N << 2]; #define mi(x) node[x].mi inline void push_up(const int curr) { mi(curr) = min(mi(ls(curr)),mi(rs(curr))); } inline void update(const int curr, const int pos, const int val, const int l = 1, const int r = n + 2) { if (l == r) { mi(curr) = val; return; } const int mid = l + r >> 1; if (pos <= mid)update(ls(curr), pos, val, l, mid); else update(rs(curr), pos, val, mid + 1, r); push_up(curr); } inline int queryMex(const int curr, const int pos, const int l = 1, const int r = n + 2) { if (l == r)return l; const int mid = l + r >> 1; if (mi(ls(curr)) < pos)return queryMex(ls(curr), pos, l, mid); return queryMex(rs(curr), pos, mid + 1, r); } vector<int> seg[N]; inline void solve() { cin >> n; forn(i, 1, n)cin >> a[i], t[a[i]].push_back(i); forn(i, 1, n+1) { int l = 1; for (const auto r : t[i]) { if (l == r) { l = r + 1; continue; } seg[r - 1].push_back(l), l = r + 1; } if (l < n)seg[n].push_back(l); } forn(r, 1, n) { update(1, a[r], r); for (const auto l : seg[r])vis[queryMex(1, l)] = true; } int mex = 1; while (vis[mex])mex++; cout << mex; } signed int main() { // MyFile Spider //------------------------------------------------------ // clock_t start = clock(); int test = 1; // read(test); // cin >> test; forn(i, 1, test)solve(); // while (cin >> n, n)solve(); // while (cin >> test)solve(); // clock_t end = clock(); // cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; }
一些细节
本题注意
剪枝参照
#include <bits/stdc++.h> // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") // #define isPbdsFile #ifdef isPbdsFile #include <bits/extc++.h> #else #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/rope> #endif using namespace std; using namespace __gnu_cxx; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> tii; typedef tuple<ll, ll, ll> tll; typedef unsigned int ui; typedef unsigned long long ull; typedef __int128 i128; #define hash1 unordered_map #define hash2 gp_hash_table #define hash3 cc_hash_table #define stdHeap std::priority_queue #define pbdsHeap __gnu_pbds::priority_queue #define sortArr(a, n) sort(a+1,a+n+1) #define all(v) v.begin(),v.end() #define yes cout<<"YES" #define no cout<<"NO" #define Spider ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); #define MyFile freopen("..\\input.txt", "r", stdin),freopen("..\\output.txt", "w", stdout); #define forn(i, a, b) for(int i = a; i <= b; i++) #define forv(i, a, b) for(int i=a;i>=b;i--) #define ls(x) (x<<1) #define rs(x) (x<<1|1) #define endl '\n' //用于Miller-Rabin [[maybe_unused]] static int Prime_Number[13] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; template <typename T> int disc(T* a, int n) { return unique(a + 1, a + n + 1) - (a + 1); } template <typename T> T lowBit(T x) { return x & -x; } template <typename T> T Rand(T l, T r) { static mt19937 Rand(time(nullptr)); uniform_int_distribution<T> dis(l, r); return dis(Rand); } template <typename T1, typename T2> T1 modt(T1 a, T2 b) { return (a % b + b) % b; } template <typename T1, typename T2, typename T3> T1 qPow(T1 a, T2 b, T3 c) { a %= c; T1 ans = 1; for (; b; b >>= 1, (a *= a) %= c)if (b & 1)(ans *= a) %= c; return modt(ans, c); } template <typename T> void read(T& x) { x = 0; T sign = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-')sign = -1; ch = getchar(); } while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } x *= sign; } template <typename T, typename... U> void read(T& x, U&... y) { read(x); read(y...); } template <typename T> void write(T x) { if (typeid(x) == typeid(char))return; if (x < 0)x = -x, putchar('-'); if (x > 9)write(x / 10); putchar(x % 10 ^ 48); } template <typename C, typename T, typename... U> void write(C c, T x, U... y) { write(x), putchar(c); write(c, y...); } template <typename T11, typename T22, typename T33> struct T3 { T11 one; T22 tow; T33 three; bool operator<(const T3 other) const { if (one == other.one) { if (tow == other.tow)return three < other.three; return tow < other.tow; } return one < other.one; } T3() { one = tow = three = 0; } T3(T11 one, T22 tow, T33 three) : one(one), tow(tow), three(three) { } }; template <typename T1, typename T2> void uMax(T1& x, T2 y) { if (x < y)x = y; } template <typename T1, typename T2> void uMin(T1& x, T2 y) { if (x > y)x = y; } constexpr int N = 2e5 + 10; int n, q; vector<int> t[N]; int a[N]; bool vis[N]; int cnt; constexpr int INF = 1e9 + 7; struct Node { int mi; } node[N << 2]; #define mi(x) node[x].mi inline void push_up(const int curr) { mi(curr) = min(mi(ls(curr)),mi(rs(curr))); } inline void update(const int curr, const int pos, const int val, const int l = 1, const int r = n + 2) { if (l == r) { mi(curr) = val; return; } const int mid = l + r >> 1; if (pos <= mid)update(ls(curr), pos, val, l, mid); else update(rs(curr), pos, val, mid + 1, r); push_up(curr); } inline int queryMex(const int curr, const int pos, const int l = 1, const int r = n + 2) { if (l == r)return l; const int mid = l + r >> 1; if (mi(ls(curr)) < pos)return queryMex(ls(curr), pos, l, mid); return queryMex(rs(curr), pos, mid + 1, r); } vector<int> seg[N]; inline void solve() { cin >> n; forn(i, 1, n)cin >> a[i], t[a[i]].push_back(i); forn(i, 1, n+1) { int l = 1; bool isAdd = false; for (const auto r : t[i]) { if (l == r) { l = r + 1; continue; } if (r - l >= i - 1) { isAdd = true; seg[r - 1].push_back(l); } l = r + 1; } if (l < n) { if (n - l + 1 >= i - 1) { isAdd = true; seg[n].push_back(l); } } if (!isAdd)break; } forn(r, 1, n) { update(1, a[r], r); for (const auto l : seg[r])vis[queryMex(1, l)] = true; } int mex = 1; while (vis[mex])mex++; cout << mex; } signed int main() { // MyFile Spider //------------------------------------------------------ // clock_t start = clock(); int test = 1; // read(test); // cin >> test; forn(i, 1, test)solve(); // while (cin >> n, n)solve(); // while (cin >> test)solve(); // clock_t end = clock(); // cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统