求助,从早上调到现在……本来自己写的调调调调不出来就仿照第二篇题解又写了一次,但还是 WA 两个点,再改下去就快变成复制的了,求 dalao 调下。
至于为什么阈值是两千……发现阈值越大 WA 的越少,再大就 TLE,搞不好可能与这个有关,但真的查不出来问题,对拍拍两千组各种大小数据也没问题。
#include <bits/stdc++.h>
#define lint long long
using namespace std;
inline int read(){
char c;int f=1,res=0;
while(c=getchar(),!isdigit(c))if(c=='-')f*=-1;
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res*f;
}
const int N=1e5+5,L=2000,inf=1e8;
int n,m,a[N],lst=0;
int cnt[N],id[N];
vector<int> ans[N],p[N],bid;
inline void umin(int &x,int y)
{if(y<x)x=y;}
inline void calc(int ix,bool t){
if(t)bid.push_back(ix);
ans[ix].resize(n+5);
for(int i=1;i<=n+1;++i)
ans[ix][i]=inf;
for(int i=1,j=inf;i<=n;++i){
if(a[i]==ix)j=0;
umin(ans[ix][a[i]],j++);
}
for(int i=n,j=inf;i>=1;--i){
if(a[i]==ix)j=0;
umin(ans[ix][a[i]],j++);
}p[ix].resize(0);
}
inline void init(){
for(int i=1;i<=n+1;++i)
if(cnt[i]>L)
calc(i,true);
}
inline void merge0(int ix,int iy){
int i=0,j=0;
vector<int> res;
int sx=p[ix].size(),sy=p[iy].size();
while(i<sx&&j<sy){
if(p[ix][i]<p[iy][j])
res.push_back(p[ix][i++]);
else res.push_back(p[iy][j++]);
}
while(i<sx)res.push_back(p[ix][i++]);
while(j<sy)res.push_back(p[iy][j++]);
p[iy]=res;
}inline void merge1(int ix,int iy)
{for(int i:p[ix])a[i]=iy;}
inline void merge2(int ix,int iy){
for(int i=1;i<=n;++i)
if(a[i]==ix)a[i]=iy;
}
inline void uans(int ix,int iy){
for(int i:bid)
umin(ans[i][iy],ans[i][ix]);
}
inline void cg(int x,int y){
int &ix=id[x],&iy=id[y];
if(!cnt[ix]||x==y)return;
if(!cnt[iy]){
iy=ix;ix=0;
return;
}
if(cnt[ix]>cnt[iy])
swap(ix,iy);
if(cnt[ix]>L&&cnt[iy]>L)
merge2(ix,iy),calc(iy,false);
else{
if(cnt[ix]+p[iy].size()<=L)
merge1(ix,iy),uans(ix,iy),merge0(ix,iy);
else
merge2(ix,iy),calc(iy,cnt[iy]<=L&&cnt[iy]+cnt[ix]>L);
}
cnt[iy]+=cnt[ix];cnt[ix]=0;
p[ix].resize(0);ix=0;
}
inline int query0(int x,int y){
int res=inf,i=0,j=0;
int sx=p[x].size(),sy=p[y].size();
while(i<sx&&j<sy){
if(p[x][i]<p[y][j])
umin(res,p[y][j]-p[x][i++]);
else umin(res,p[x][i]-p[y][j++]);
}
while(i<sx)umin(res,abs(p[x][i++]-p[y][sy-1]));
while(j<sy)umin(res,abs(p[y][j++]-p[x][sx-1]));
return res;
}
inline int solve(int x,int y){
int ix=id[x],iy=id[y];
if(!cnt[ix]||!cnt[iy])return inf;
if(x==y)return 0;
int res=query0(ix,iy);
if(cnt[iy]>L)umin(res,ans[iy][ix]);
if(cnt[ix]>L)umin(res,ans[ix][iy]);
return res;
}
int main(){
// freopen("dat.in","r",stdin);
// freopen("debug.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;++i){
int x=a[i]=read()+1;
id[x]=x;++cnt[x];
p[x].push_back(i);
}init();
for(int i=1;i<=m;++i){
int op=read();
int x=(read()^lst)+1,y=(read()^lst)+1;
if(op==1)
cg(x,y);
else if(op==2){
lst=solve(x,y);
if(lst<N)printf("%d\n",lst);
else puts("Ikaros"),lst=0;
}//lst=0;
}
return 0;
}