CF413E Maze 2D

### 线段树

题目
宽度只有\(1\)的话怎么做?
用线段树维护一下\(dis\)表示\(l-r\)区间的距离
那么宽度为\(2\)的也一样啊
就可以设四个距离
表示左上到右上,左上到右下,左下到右上,左下到右下
这样就可以查询了


#include<bits/stdc++.h>
using namespace std;
const int maxn=2*1e5+10,inf=0x3f3f3f3f;
int n,m,tu[10][maxn];
struct tree{
    int dt[5];//左上到右上 左上到右下 左下到右上 左下到右下
}tr[maxn<<2];
inline void pushup(int p){
    tree ls=tr[p<<1],rt=tr[p<<1|1];
    tr[p].dt[1]=min(inf,min(ls.dt[1]+rt.dt[1],ls.dt[2]+rt.dt[3])+1);
    tr[p].dt[2]=min(inf,min(ls.dt[1]+rt.dt[2],ls.dt[2]+rt.dt[4])+1);
    tr[p].dt[3]=min(inf,min(ls.dt[3]+rt.dt[1],ls.dt[4]+rt.dt[3])+1);
    tr[p].dt[4]=min(inf,min(ls.dt[4]+rt.dt[4],ls.dt[3]+rt.dt[2])+1);
    return;
}
void build(int p,int l,int r){
    if(l==r){
        tr[p].dt[1]=tr[p].dt[2]=tr[p].dt[3]=tr[p].dt[4]=inf;
        if(tu[1][l]) tr[p].dt[1]=0;
        if(tu[2][l]) tr[p].dt[4]=0;
        if(tu[1][l] && tu[2][l]) tr[p].dt[2]=tr[p].dt[3]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    pushup(p);
}
inline tree qry(int p,int l,int r,int x,int y){
    if(x<=l && r<=y) return tr[p];
    int mid=(l+r)>>1;
    tree ls,rt,res;
    bool fl1=0,fl2=0;
    if(x<=mid) ls=qry(p<<1,l,mid,x,y),fl1=1;
    if(mid<y) rt=qry(p<<1|1,mid+1,r,x,y),fl2=1;
    if(fl1 && !fl2) return ls;
    if(!fl1 && fl2) return rt;
    res.dt[1]=min(inf,min(ls.dt[1]+rt.dt[1],ls.dt[2]+rt.dt[3])+1);
    res.dt[2]=min(inf,min(ls.dt[1]+rt.dt[2],ls.dt[2]+rt.dt[4])+1);
    res.dt[3]=min(inf,min(ls.dt[3]+rt.dt[1],ls.dt[4]+rt.dt[3])+1);
    res.dt[4]=min(inf,min(ls.dt[4]+rt.dt[4],ls.dt[3]+rt.dt[2])+1);
    return res;
}
inline int ask(int x,int y){
    int a=(x-1)%n+1,b=(y-1)%n+1;
    if(a>b){ swap(x,y);swap(a,b); }
    tree xx=qry(1,1,n,a,b);
    if(x<=n && y<=n) return xx.dt[1];
    if(x<=n && y>n) return xx.dt[2];
    if(x>n && y<=n) return xx.dt[3];
    if(x>n && y>n) return xx.dt[4];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=2;i++){
        string s;cin>>s;
        for(int j=0;j<n;j++) if(s[j]=='.') tu[i][j+1]=1;
    }
    build(1,1,n);
    while(m--){
        int x,y;scanf("%d%d",&x,&y);
        int ans=ask(x,y);
        if(ans>=inf) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}
01-04 17:32