给出 数组 (a{})
(q)次操作
1、查询区间(l) ~ (r) 中每个数字出现次数
的 (mex)
2、单点修改。
出现次数的mex
注意不是数值的 mex
(1 leq a_i leq 10^9)
考虑离散化 因为数字较大 (map) 自带 (log) 和 大常数。。
然后用带修莫队维护的复杂度就会变成 (n^{5/3}* log n)
显然是跑不过去的。。
离散化有一个问题 就是你要把询问中的修改的数值也离散化
然后 用一个 (cntt_i) 记录 (i) 出现的次数 (tot_i) 记录出现 (i) 次的个数
带修莫队有一个时间戳 排序应该是按 (l)所在的块 -> (r)所在的块 -> 当前修改的时间戳。。
带修莫队的块大小应该是 (n^{2/3})
对于这道题还有一个不太严谨的结论:求(mex)的复杂度每次扫一遍不会超过 (sqrt n)
(nsqrt n le n^{5/3})
#include<bits/stdc++.h>
using namespace std ;
int n , Q ;
vector < int > v , b ;
const int N = 2e5 + 10 ;
int bl[N] ;
struct node { int l , r , id , t ; } q[N] ;
struct change { int x , val ; } c[N] ;
int tot[N] , cntt[N] ;
inline void add(int x) {
-- tot[cntt[x]] ;
++ tot[++ cntt[x]] ;
}
inline void del(int x) {
-- tot[cntt[x]] ;
++ tot[-- cntt[x]] ;
}
inline void modify(int now , int i) {
if(q[i].l <= c[now].x && c[now].x <= q[i].r) {
del(v[c[now].x]) ;
add(c[now].val) ;
} swap(v[c[now].x] , c[now].val) ;
}
int ans[N] ;
signed main() {
ios :: sync_with_stdio(false) ;
cin.tie(nullptr) ; cout.tie(nullptr) ;
cin >> n >> Q ; int unt = pow(n , 2.0 / 3.0) ;
for(register int i = 0 ; i < n ; i ++) { int x ; cin >> x ; v.push_back(x) ; }
for(register int i = 0 ; i < n ; i ++) { b.push_back(v[i]) ; bl[i] = (i - 1) / unt + 1 ; }
int cnt , cnt2 ; cnt = cnt2 = 0 ;
for(register int i = 0 ; i < Q ; i ++) { int opt , x , y ; cin >> opt >> x >> y ;
if(opt == 1) { ++ cnt ; q[cnt] = {-- x , -- y , cnt , cnt2} ; }
if(opt == 2) { ++ cnt2 ; c[cnt2] = { -- x , y } ; b.push_back(y) ; }
}
sort(b.begin() , b.end()) ; b.erase(unique(b.begin() , b.end()) , b.end()) ;
for ( int & x : v ) x = lower_bound(b.begin() , b.end() , x) - b.begin() ;
for(register int i = 1 ; i <= cnt2 ; i ++) { c[i].val = lower_bound(b.begin() , b.end() , c[i].val) - b.begin() ; }
sort(q + 1 , q + cnt + 1 , [] (node x , node y) {
if(bl[x.l] ^ bl[y.l]) return x.l < y.l ;
if(bl[x.r] ^ bl[y.r]) return x.r < y.r ;
return x.t < y.t ;
}) ;
int l = 1 , r = 0 , now = 0 ;
for(register int i = 1 ; i <= cnt ; i ++) {
while(l > q[i].l) add(v[-- l]) ;
while(r < q[i].r) add(v[++ r]) ;
while(l < q[i].l) del(v[l ++]) ;
while(r > q[i].r) del(v[r --]) ;
while(now < q[i].t) modify(++ now , i) ;
while(now > q[i].t) modify(now -- , i) ;
for(ans[q[i].id] = 1 ; tot[ans[q[i].id]] > 0 ; ++ ans[q[i].id]) ;
} for(register int i = 1 ; i <= cnt ; i ++) cout << ans[i] << '
' ;
return 0 ;
}