CF2093D

Solution

分制模版题,先处理第一个问题。定义搜索状态 ${dfs}(x,y,l,mn,mx)$ 表示当前在 $(x,y)$ 这个位置,当前块的边长为 $l$,当前块内的最大和最小值 $mx,mn$。

初始从最大的那个也就是右下角开始。

void query1(LL x,LL y,LL l,LL mn,LL mx){
    if(l==1){//找到
        cout<<mn<<endl;
        return ;
    }
    LL len=mx-mn+1;//方便处理
    if(x<=l/2&&y<=l/2){//左上角
        query1(x,y,l/2,mn,mn+len/4-1);
    }
    if(x>l/2&&y>l/2){//右下角
        query1(x-l/2,y-l/2,l/2,mn+len/4,mn+len/2-1);
    }
    if(x>l/2&&y<=l/2){//左下角
        query1(x-l/2,y,l/2,mn+len/2,mn+len/4*3-1);
    }
    if(x<=l/2&&y>l/2){//右上角
        query1(x,y-l/2,l/2,mn+len/4*3,mx);
    }
}

在第二个问题中只需要加上当前查找的值 $d$ 即可。

从左上角开始,找范围。

void query2(LL x,LL y,LL l,LL d,LL mn,LL mx){
    if(l==1){
        cout<<x<<' '<<y<<endl;
        return ;
    }
    LL len=mx-mn+1;
    if(d<=mn+len/4-1){
        query2(x,y,l/2,d,mn,mn+len/4-1);
    }
    if(d>=mn+len/4&&d<=mn+len/2-1){
        query2(x+l/2,y+l/2,l/2,d,mn+len/4,mn+len/2-1);
    }
    if(d>=mn+len/2&&d<=mn+len/4*3-1){
        query2(x+l/2,y,l/2,d,mn+len/2,mn+len/4*3-1);
    }
    if(d>=mn+len/4*3&&d<=mx){
        query2(x,y+l/2,l/2,d,mn+len/4*3,mx);
    }
}

Code

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
LL n,q,t,pw[100]={1};
void query1(LL x,LL y,LL l,LL mn,LL mx){
    if(l==1){
        cout<<mn<<endl;
        return ;
    }
    LL len=mx-mn+1;
    if(x<=l/2&&y<=l/2){
        query1(x,y,l/2,mn,mn+len/4-1);
    }
    if(x>l/2&&y>l/2){
        query1(x-l/2,y-l/2,l/2,mn+len/4,mn+len/2-1);
    }
    if(x>l/2&&y<=l/2){
        query1(x-l/2,y,l/2,mn+len/2,mn+len/4*3-1);
    }
    if(x<=l/2&&y>l/2){
        query1(x,y-l/2,l/2,mn+len/4*3,mx);
    }
}
void query2(LL x,LL y,LL l,LL d,LL mn,LL mx){
    //cout<<x<<' '<<y<<endl;
    if(l==1){
        cout<<x<<' '<<y<<endl;
        return ;
    }
    LL len=mx-mn+1;
    if(d<=mn+len/4-1){
        query2(x,y,l/2,d,mn,mn+len/4-1);
    }
    if(d>=mn+len/4&&d<=mn+len/2-1){
        query2(x+l/2,y+l/2,l/2,d,mn+len/4,mn+len/2-1);
    }
    if(d>=mn+len/2&&d<=mn+len/4*3-1){
        query2(x+l/2,y,l/2,d,mn+len/2,mn+len/4*3-1);
    }
    if(d>=mn+len/4*3&&d<=mx){
        query2(x,y+l/2,l/2,d,mn+len/4*3,mx);
    }
}
int main(){
    for(int i=1;i<=60;i++) pw[i]=pw[i-1]*2;
    cin>>t;
    while(t--){
        cin>>n>>q;
        while(q--){
            LL x,y;char c1,c2;
            cin>>c1>>c2;
            if(c1=='-'){
                cin>>x>>y;
                query1(x,y,pw[n],1,pw[n*2]);
            }else {
                cin>>x;
                query2(1,1,pw[n],x,1,pw[n*2]);
            }
        }
    }
    return 0;
}