Single Modification Moqun + Discrete CodeForces - 940F [Machine Learning]
https://cn.vjudge.net/contest/304248#problem/F
meaning of the title
Given n n n n n n n n numbers and m operations, array subscripts [1, n] ((a_i Leq 1E ^ 9))) are divided into two types:
- 1 x y - mex of the set {_ (c_0, c_1, c_2,..., C {10^ 9}_) in the query interval [x, y], and (c_i_) denotes the number of times the value I appears in [l,r], i.e. the minimum positive integer (number of times) that does not appear.
- 2 x y - Modify a[x] to y
Analysis
If you don't need discretization, I'll add it to my last blog.
But I tuned BUG fast for two hours. TLE 12 didn't know how many times I saw it.
The complexity of the Moche Team with modification is (O(n ^{ frac {5} {3}}). So [block = int] pow (n, 2.0/3);]
Keep in mind that because of this size, the Lord was forced to complete.
First, the input data is compressed to the range of (n+q).
Record the number of occurrences of each number in the (sum) array and the number of occurrences in the (mark) array. Then the question of the title is converted to the position where the zero value appears for the first time in the (mark) array.
The reasoning mark array must take nearly(O(n)\ time to find the zero position every time so I won't
However, it would not exceed (O ( sqrt {n})). Because to fill (mark_1,mark_2,...,mark_k), at least ( frac {k+1)} {2}\) elements are needed. Because the total length is limited, it is certain that they will not exceed \\\\\\\\\\ Therefore, the total complexity of maintaining the answer is no less than (O(m\sqrt{n}).
In addition, we should also pay attention to expanding the scope of the interval first and then reducing it to prevent the occurrence of the interval(r < l). (In this question, it may lead to more subtraction of intermediate results, leading to (mark) array crossing the boundary.)
And the adjustment of the time axis is better to put it back as far as possible.
Code
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5+5; int n, m; int cur_a[maxn<<1]; int cnt, cnt_; int a[maxn]; int sum[maxn<<1]; int mark[maxn]; int block; int ans[maxn]; int belong[maxn]; struct node{ int l, r, id, t; bool operator < (const node &a) const { if(belong[l] == belong[a.l] && belong[r] == belong[a.r]) { return t < a.t; } if(belong[l] == belong[a.l]) { return r < a.r; } return l < a.l; } }Q[maxn]; struct Change{ int x, now, cur; }C[maxn]; void del(int x) { mark[sum[x]] --; sum[x] --; mark[sum[x]] ++; } void add(int x) { mark[sum[x]] --; sum[x] ++; mark[sum[x]] ++; } void init() { block = (int)pow(n, 2.0/3.0); cnt = cnt_ = 0; memset(mark, 0, sizeof(mark)); memset(sum, 0, sizeof(sum)); } void dis() { for(int i = 1; i <= n; i++) { a[i] = cur_a[i]; } sort(cur_a+1, cur_a+1+n+cnt_); int tag = unique(cur_a+1, cur_a+1+n+cnt_) - (cur_a+1); for(int i = 1; i <= n; i++) { a[i] = lower_bound(cur_a+1, cur_a+1+tag, a[i]) - cur_a; } for(int i = 1; i <= cnt_; i++) { C[i].now = lower_bound(cur_a+1, cur_a+1+tag, C[i].now) - cur_a; C[i].cur = lower_bound(cur_a+1, cur_a+1+tag, C[i].cur) - cur_a; } mark[0] = tag + 10; } int main() { // fopen("in.txt", "r", stdin); // fopen("out.txt", "w", stdout); while(~scanf("%d%d", &n, &m)) { init(); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); cur_a[i] = a[i]; belong[i] = (i-1)/block + 1; } int f, x, y; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &f, &x, &y); if(f == 1) { Q[++cnt].l = x; Q[cnt].r = y; Q[cnt].id = cnt; Q[cnt].t = cnt_; } else { C[++cnt_].x = x; C[cnt_].now = y; C[cnt_].cur = a[x]; a[x] = y; cur_a[n+cnt_] = y; } } dis(); sort(Q+1, Q+1+cnt); int l = 1, r = 0; int Time = 0; for(int i = 1; i <= cnt; i++) { while(l > Q[i].l) { l--; add(a[l]); } while(r < Q[i].r) { r++; add(a[r]); } while(l < Q[i].l) { del(a[l]); l++; } while(r > Q[i].r) { del(a[r]); r--; } while(Time < Q[i].t) { Time++; if(Q[i].l <= C[Time].x && C[Time].x <= Q[i].r) { add(C[Time].now); del(C[Time].cur); } a[C[Time].x] = C[Time].now; } while(Time > Q[i].t) { if(Q[i].l <= C[Time].x && C[Time].x <= Q[i].r) { add(C[Time].cur); del(C[Time].now); } a[C[Time].x] = C[Time].cur; Time--; } for(ans[Q[i].id] = 1; mark[ans[Q[i].id]]; ans[Q[i].id]++); } for(int i = 1; i <= cnt; i++) { printf("%d\n", ans[i]); } } return 0; }