ABC 略
D
分形。第一个询问我们用dfs传此时我们确定的这个数所在行列的范围,和这个范围中的最大值,通过比对目标格数的行列和目前搜索范围的行列关系锁定田字格的方位,下一步搜索,直到范围为1。第二个询问同理,通过比对这个值和最大值的关系锁定在田字格的方位。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int T,n,q,b[62];
void init()
{
}
void dfs(int x,int y,int l1,int r1,int l2,int r2,int val)
{ if(l1==r1) {cout<<val<<endl; return ;}int num=(r1-l1+1)*(r2-l2+1)/4;if(x<=(l2+r2)/2&&y<=(l1+r1)/2) dfs(x,y,l1,(l1+r1)/2,l2,(l2+r2)/2,val-3*num);if(x>(l2+r2)/2&&y>(l1+r1)/2) dfs(x,y,(l1+r1+1)/2,r1,(l2+r2+1)/2,r2,val-2*num);if(x>(l2+r2)/2&&y<=(l1+r1)/2) dfs(x,y,l1,(l1+r1)/2,(l2+r2+1)/2,r2,val-num);if(x<=(l2+r2)/2&&y>(l1+r1)/2) dfs(x,y,(l1+r1+1)/2,r1,l2,(l2+r2)/2,val);
}
void dfs1(int x,int l1,int r1,int l2,int r2,int val)
{if(l1==r1){cout<<l2<<" "<<l1<<endl;return ;}int num=(r1-l1+1)*(r2-l2+1)/4;if(x>val-num) dfs1(x,(l1+r1+1)/2,r1,l2,(l2+r2)/2,val);if(x<=val-num&&x>val-num*2) dfs1(x,l1,(l1+r1)/2,(l2+r2+1)/2,r2,val-num);if(x<=val-num*2&&x>val-num*3) dfs1(x,(l1+r1+1)/2,r1,(l2+r2+1)/2,r2,val-num*2);if(x<=val-num*3) dfs1(x,l1,(l1+r1)/2,l2,(l2+r2)/2,val-num*3);
}
void solve()
{cin>>n>>q;init();for(int i=1;i<=q;i++){char c[2];cin>>c[0]>>c[1];if(c[0]=='-'){int x,y;cin>>x>>y;dfs(x,y,1,b[n],1,b[n],b[2*n]);}else{int x;cin>>x;dfs1(x,1,b[n],1,b[n],b[2*n]);}}
}
signed main()
{b[0]=1;for(int i=1;i<=60;i++)b[i]=b[i-1]*2;std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>T;while(T--) solve();
}