求卡常,一个上午了(80)
查看原帖
求卡常,一个上午了(80)
756684
寄风孤影楼主2023/7/1 14:22
#include <bits/stdc++.h>
using namespace std;

inline int read(){ 
    int s = 0 , f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9'){
        s = (s << 1) + (s << 3) + (c ^ 48);
        c = getchar();
    }
    return f * s;
}
inline void print(int x){
    if(x < 0) putchar('-') , x *= -1;
    if(x > 9) print(x / 10);
    putchar(x % 10 + '0');
}
const int M = 385 , N = 100005 , B = N / M + 6;
int len , n , m , cntt[B] , pos[N][B] , l[B] , r[B] , cnt , fir[B][M] , lst[B][M] , dis[B][M][M];
//pos[i][j]:j块i的离散值
struct node{
    int Rank , x , id;
} a[N];
bool cmp1(node a , node b){
    return a.x < b.x;
}
bool cmp2(node a , node b){
    return a.id < b.id;
}
inline void init(){
    len = M - 5;
	cnt = n / len + (bool) (n % len);
    for(int i = 1 , j = 1;i <= n;i += len , ++j){
    	l[j] = r[j - 1] + 1;
		r[j] = i + len;
	}
    r[cnt] = min(n , r[cnt]);
    for(int i = 1;i <= cnt;++i){
        sort(a + l[i] , a + r[i] + 1 , cmp1);
        a[l[i]].Rank = 1;
		pos[a[l[i]].x][i] = a[l[i]].Rank;
        for(int j = l[i] + 1;j <= r[i];++j){
            if(a[j].x != a[j - 1].x){
            	a[j].Rank = a[j - 1].Rank + 1;
			}
			else a[j].Rank = a[j - 1].Rank;
            pos[a[j].x][i] = a[j].Rank;
        }
        cntt[i] = a[r[i]].Rank;
        sort(a + l[i] , a + r[i] + 1 , cmp2);
    }
    memset(dis , 0x3f , sizeof(dis));
    for(int i = 1;i <= cnt;++i){
        for(int j = l[i];j <= r[i];++j){
        	if(!fir[i][a[j].Rank]){
        		fir[i][a[j].Rank] = j;
			}
		}
        for(int j = r[i];j >= l[i];--j){
        	if(!lst[i][a[j].Rank]){
        		lst[i][a[j].Rank] = j;
			}	
		}
        for(int j = l[i];j <= r[i];++j){
            for(int k = j + 1;k <= r[i];++k){
                int minn = min(a[j].Rank , a[k].Rank) , maxn = max(a[j].Rank , a[k].Rank);
                dis[i][minn][maxn] = min(dis[i][minn][maxn],k-j);
        	}
		}
    }
    return;
}
inline void update(int x , int y){
    for(int i = 1;i <= cnt;++i){
        if(!pos[x][i]) continue;
        else if(!pos[y][i]){
            pos[y][i] = pos[x][i];
            pos[x][i] = 0;
        }
	    else{
	        int posx = pos[x][i] , posy = pos[y][i];
            if(posx > posy){
                for(int j = 1;j <= posy;++j)
                    dis[i][j][posy] = min(dis[i][j][posy] , dis[i][j][posx]);
                for(int j = posy + 1;j <= posx;++j)
                    dis[i][posy][j] = min(dis[i][posy][j] , dis[i][j][posx]);
                for(int j = posx + 1;j <= cntt[i];++j)
                    dis[i][posy][j] = min(dis[i][posy][j] , dis[i][posx][j]);
            }
            else{
                for(int j = 1;j <= posx;++j)
                    dis[i][j][posy] = min(dis[i][j][posy] , dis[i][j][posx]);
                for(int j = posx + 1;j <= posy;++j)
                    dis[i][j][posy] = min(dis[i][j][posy] , dis[i][posx][j]);
                for(int j=posy + 1;j <= cntt[i];++j)
                    dis[i][posy][j] = min(dis[i][posy][j] , dis[i][posx][j]);
            }
            fir[i][posy] = min(fir[i][posx] , fir[i][posy]);
			lst[i][posy] = max(lst[i][posx] , lst[i][posy]);
            fir[i][posx] = lst[i][posx] = pos[x][i] = 0;
		}
    }
}
inline int getans(int x , int y){
    int ans = dis[0][0][0] , ex , ey , nx = -1e9 , ny = -1e9;
    if(x == y){
        for(int i = 1;i <= cnt;++i){
        	if(pos[x][i]) return 0;
		}
        return -1;
    }
    for(int i = 1;i <= cnt;++i) ans = min(ans , dis[i][min(pos[x][i] , pos[y][i])][max(pos[x][i] , pos[y][i])]);
    for(int i = 1;i <= cnt;++i){
        if(ex = fir[i][pos[x][i]]) ans = min(ans , ex - ny);
        if(ey = fir[i][pos[y][i]]) ans = min(ans , ey - nx);
        if(ex) nx = lst[i][pos[x][i]];
		if(ey) ny = lst[i][pos[y][i]];
    }
    return ans >= n ? -1 : ans;
}
signed main(){
    n = read() , m = read();
    for(int i = 1;i <= n;++i){
        a[i].x = read();
        a[i].id = i;
    }
    init();
    int ans = 0;
    for(int i = 1;i <= m;++i){
        int op = read() , x = read() ^ ans , y = read() ^ ans;
        if(op == 1){
            if(x != y){
                update(x , y);
            }
        }
        else{
            ans = getans(x , y);
            if(ans == -1){
                puts("Ikaros");
                ans = 0;
            }
            else{
                print(ans);
                putchar('\n');
            }
        }
    }
    return 0;
}
2023/7/1 14:22
加载中...