怀疑是单独块出了问题。
WA。
有对拍器的话也可以发给我
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int Len = 1e5 + 5 , SIZE = 330;
int n,m,fr[SIZE][Len],col[Len],fa[Len],cnt[SIZE][Len],sum[SIZE][SIZE],vt,t,L[SIZE],R[SIZE],pos[Len],VL[SIZE],VR[SIZE],Vpos[Len],a[Len];
void makeSet(int x){for(int i = 1 ; i <= x ; i ++) fa[i] = i;}
int findSet(int x){return fa[x] == x ? fa[x] : fa[x] = findSet(fa[x]);}
inline void merge(int x,int X,int Y)
{
if(!fr[x][X]) return;
else if(!fr[x][Y]){fr[x][Y] = fr[x][X] , col[fr[x][Y]] = Y;}
else fa[fr[x][X]] = fr[x][Y];
fr[x][X] = 0;
}
inline void build(int x,int l,int r,int X,int Y)
{
for(int i = L[x] ; i <= R[x] ; i ++){a[i] = col[findSet(i)] ; fr[x][a[i]] = 0;}
for(int i = l ; i <= r ; i ++) if(a[i] == X) a[i] = Y;
for(int i = L[x] ; i <= R[x] ; i ++)
{
if(!fr[x][a[i]]){fr[x][a[i]] = i;col[fr[x][a[i]]] = a[i];}
fa[i] = fr[x][a[i]];
}
}
inline void upd(int l,int r,int X,int Y)
{
if(X == Y) return;
int LL = pos[l] , RR = pos[r];
int numb = 0 , Tmp = 0;
if(LL == RR)
{
for(int i = l ; i <= r ; i ++) if(col[findSet(i)] == X) numb ++;
for(int i = LL ; i <= t ; i ++) sum[i][Vpos[X]] -= numb , sum[i][Vpos[Y]] += numb , cnt[i][X] -= numb , cnt[i][Y] += numb;
build(LL , l , r , X , Y);
return;
}
for(int i = l ; i <= R[LL] ; i ++) if(col[findSet(i)] == X) numb ++;
for(int i = LL + 1 ; i <= RR - 1 ; i ++) numb += Tmp , sum[i][Vpos[X]] -= numb , sum[i][Vpos[Y]] += numb , Tmp = cnt[i + 1][X] - cnt[i][X] , cnt[i][X] -= numb , cnt[i][Y] += numb;
for(int i = L[RR] ; i <= r ; i ++) if(col[findSet(i)] == X) numb ++;
for(int i = RR ; i <= t ; i ++) sum[i][Vpos[X]] -= numb , sum[i][Vpos[Y]] += numb , cnt[i][X] -= numb , cnt[i][Y] += numb;
for(int i = LL + 1 ; i <= RR - 1 ; i ++) merge(i , X , Y);
build(LL , l , R[LL] , X , Y);
build(RR , L[RR] , r , X , Y);
return;
}
int UsedSum[Len],UsedBlock[SIZE];
inline int qry(int l,int r,int k)
{
int LL = pos[l] , RR = pos[r];
if(k > r - l + 1) return -1;
if(LL == RR)
{
for(int i = l ; i <= r ; i ++) UsedBlock[Vpos[col[findSet(i)]]] ++ , UsedSum[col[findSet(i)]] ++;
for(int j = 1 ; j <= vt ; j ++)
{
if(k > UsedBlock[j]) k -= UsedBlock[j];
else
{
for(int p = VL[j] ; p <= VR[j] ; p ++)
{
if(k > UsedSum[p]) k -= UsedSum[p];
else
{
for(int i = l ; i <= r ; i ++) UsedBlock[Vpos[col[findSet(i)]]] -- , UsedSum[col[findSet(i)]] --;
return p;
}
}
}
}
}
for(int i = l ; i <= R[LL] ; i ++) UsedBlock[Vpos[col[findSet(i)]]] ++ , UsedSum[col[findSet(i)]] ++;
for(int i = L[RR] ; i <= r ; i ++) UsedBlock[Vpos[col[findSet(i)]]] ++ , UsedSum[col[findSet(i)]] ++;
for(int j = 1 ; j <= vt ; j ++)
{
if(k > (sum[RR - 1][j] - sum[LL][j] + UsedBlock[j])) k -= sum[RR - 1][j] - sum[LL][j] + UsedBlock[j];
else
{
for(int p = VL[j] ; p <= VR[j] ; p ++)
{
if(k > (cnt[RR - 1][p] - cnt[LL][p] + UsedSum[p])) k -= cnt[RR - 1][p] - cnt[LL][p] + UsedSum[p];
else
{
for(int i = l ; i <= R[LL] ; i ++) UsedBlock[Vpos[col[findSet(i)]]] -- , UsedSum[col[findSet(i)]] --;
for(int i = L[RR] ; i <= r ; i ++) UsedBlock[Vpos[col[findSet(i)]]] -- , UsedSum[col[findSet(i)]] --;
return p;
}
}
}
}
}
signed main()
{
int maxn = 0;
scanf("%d %d",&n,&m);
makeSet(n);
t = sqrt(n);
for(int i = 1 ; i <= n ; i ++){scanf("%d",&a[i]) ; maxn = max(maxn , a[i]);}
vt = sqrt(maxn);
for(int i = 1 ; i <= t ; i ++) L[i] = (i - 1) * t + 1 , R[i] = i * t;
R[t] = n;
for(int i = 1 ; i <= vt ; i ++) VL[i] = (i - 1) * vt + 1 , VR[i] = i * vt;
VR[vt] = maxn;
for(int i = 1 ; i <= t ; i ++)
for(int j = L[i] ; j <= R[i] ; j ++) pos[j] = i;
for(int i = 1 ; i <= vt ; i ++)
for(int j = VL[i] ; j <= VR[i] ; j ++) Vpos[j] = i;
for(int i = 1 ; i <= t ; i ++)
{
for(int j = L[i] ; j <= R[i] ; j ++)
{
if(!fr[i][a[j]]){fr[i][a[j]] = j ; col[fr[i][a[j]]] = a[j];}
fa[j] = fr[i][a[j]];
cnt[i][a[j]] ++ , sum[i][Vpos[a[j]]] ++;
}
for(int j = 1 ; j <= vt ; j ++) sum[i][j] += sum[i - 1][j];
for(int j = 1 ; j <= maxn ; j ++) cnt[i][j] += cnt[i - 1][j];
}
for(int i = 1 ; i <= m ; i ++)
{
int opt,l,r,x,y;scanf("%d %d %d %d",&opt,&l,&r,&x);
if(opt == 1){scanf("%d",&y);upd(l , r , x , y);}
else printf("%d\n",qry(l , r , x));
}
return 0;
}