题链:https://pintia.cn/problem-sets/1330210570443206656/problems/1330211663051010048
题目:
思路:希尔伯特曲线,直接递归球即可。按主对角线对称,交换x,y;副对角线对称,假设正方形变成为m,newx=m-y+1,newy=m-x+1。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,op;
ll x,y,xx1,yy1,xx2,yy2;
ll dfs1(int k,int x,int y){
if(k==1){
if(x==1&&y==1) return 1;
else if(x==2&&y==1) return 2;
else if(x==2&&y==2) return 3;
else return 4;
}
ll m = (1LL<<(k-1)),xx=(x-1)/m,yy=(y-1)/m,mm=m*m;
if(xx==0&&yy==0) return dfs1(k-1,y,x);
else if(xx>0&&yy==0) return mm+dfs1(k-1,x-m,y);
else if(xx>0&&yy>0) return (mm*2)+dfs1(k-1,x-m,y-m);
else{
y-=m;
return mm*3+dfs1(k-1,m-y+1,m-x+1);
}
}
void dfs2(int k,ll id,ll& x,ll& y){
if(k==1){
if(id==1) x=1,y=1;
else if(id==2) x=2,y=1;
else if(id==3) x=2,y=2;
else x=1,y=2;
return ;
}
ll m = (1LL<<(k-1)),mm=m*m,xx=(id-1)/mm;
id-=xx*mm;
if(xx==0){
dfs2(k-1,id,x,y);
swap(x,y);
}else if(xx==1){
dfs2(k-1,id,x,y);
x+=m;
}else if(xx==2){
dfs2(k-1,id,x,y);
x+=m,y+=m;
}else{
dfs2(k-1,id,x,y);
ll t=x;
x=m-y+1;
y=m-t+1;
y+=m;
}
}
int main(void){
scanf("%d%d",&n,&k);
while(n--){
scanf("%d%lld%lld",&op,&x,&y);
if(op==1){
printf("%lld\n",dfs1(k,x,y));
}else{
dfs2(k,x,xx1,yy1);
dfs2(k,y,xx2,yy2);
printf("%lld\n",abs(xx1-xx2)+abs(yy1-yy2));
}
}
return 0;
}