Mo + team single-point modification discrete CodeForces - 940F] [Machine Learning
https://cn.vjudge.net/contest/304248#problem/F
The meaning of problems
N and m are given number operations, the array subscripts [. 1, n] ( \ (a_i \ ^ Leq 1E. 9 \) ), divided into two operations:
- 1 xy - Query interval [x, y] in the set { \ (C_0, c_1 and, c_2, ..., C_ {10}. 9 ^ \) } of mex, the \ (C_i \) represents the value of i [L , the number of occurrences r], i.e. the smallest integer not appear (the number).
- 2 xy - to a [x] y modified
analysis
If you do not have discrete good, I'll add it to go up on a blog.
But I tune BUG tone for nearly two hours, TLE 12 met do not know how many times ...
Mo team complexity is modified with \ (O (n-^ {\ FRAC. 5} {} {}. 3) \) . So \ [block = (int) pow (n, 2.0 / 3); \]
Remember Remember, just because a piece the size of the force to rip the whole God.
To use discretization technique, the input to the data compression \ (n + q \) within the scope.
With \ (sum \) array record the number of times each number appears (after discrete), \ (Mark \) array record \ (\ sum) the number of occurrences of the number. Then the subject of inquiry is converted into: demand \ (mark \) array 0 values occur once the position.
Reason mark each array location definitely need to find nearly 0 \ (O (n) \) time of it ... so I will not ...
However, actually it does not exceed \ (O (\ n-sqrt {}) \) . Because To \ (mark_1, mark_2, ..., mark_k \) to fill it, at least \ (\ frac {k (k + 1)} {2} \) elements, since the total length is limited, certainly not so clear more than \ (O (\ n-sqrt {}) \) . Thus maintaining the overall complexity answer but also \ (O (m \ n-sqrt {}) \) .
Further, attention must be to expand the range segment, and then reduced , to prevent the occurrence interval \ (r <l \) conditions. (This problem may cause the results of multi-center cut, resulting in \ (mark \) array bounds.)
And timeline adjustments or put back as much as possible is better ...
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;
}