 /**//*
题意:给出一个地图,一些地方可以走
The ground is constructed in such a way that there is exactly one way to get from one passable cell to another passable cell without visiting any cell twice.
表明是一棵树
然后给出Q个询问,问a到b的最少转的次数
以'#'建一棵树,预处理LCA
然后读入查询,找到LCA 再分情况讨论一下cost[]即可
if LCA(a,b)=a da=0
else 考虑LCA(a,b)向上有没转 有的话da=dist[a]-dist[LCA(a,b)]-1 要-1

R*C<=100000 递归会爆
要用非递归
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;

const int MAXN = 100010;

 int dx[4]= {1,0,-1,0};
 int dy[4]= {0,1,0,-1};

char rect[MAXN];
int R,C,root;

int F[MAXN*2],B[MAXN*2];
int pos[MAXN],cost[MAXN],from[MAXN];
int done;
vector<pair<int,int> >G[MAXN];
bool vi[MAXN];

 /**//*
递归版的
void dfs(int u,int p,int dep,int turn,int k)
{
from[u]=k;
cost[u]=turn;
pos[u]=done;
F[done]=u;
B[done++]=dep;
int x=u/C,y=u%C;
for(int kk=0;kk<4;kk++)
{
int xx=x+dx[kk],yy=y+dy[kk],v=xx*C+yy;
if(xx<0||xx==R||yy<0||yy==C)continue;//out of bound
if(rect[v]!='#'||v==p)continue;
dfs(v,u,dep+1,turn+(kk!=k),kk);
//下面的要先push后才能push(v) 因为是后序
F[done]=u;
B[done]=dep;
G[u].push_back(make_pair(done++,kk));//
}
}
*/


struct State
  {
bool flag;
int u,dep,turn,k;
 State(bool flag,int u,int dep,int turn,int k):flag(flag),u(u),dep(dep),turn(turn),k(k) {}
};

void dfs(int u)//u p dep turn k
  {
stack<State>S;
S.push(State(false,u,0,0,0));
while(!S.empty())
 {
State top=S.top();
S.pop();
if(top.flag)
 {
F[done]=top.u;
B[done]=top.dep;
G[top.u].push_back(make_pair(done++,top.k));//
}
else
 {
vi[top.u]=1;
from[top.u]=top.k;
cost[top.u]=top.turn;
pos[top.u]=done;
F[done]=top.u;
B[done++]=top.dep;
int x=top.u/C,y=top.u%C;
for(int kk=0;kk<4;kk++)
 {
int xx=x+dx[kk],yy=y+dy[kk],v=xx*C+yy;
if(xx<0||xx==R||yy<0||yy==C)continue;//out of bound
if(rect[v]!='#'||vi[v])continue;
S.push(State(true,top.u,top.dep,top.turn,kk));//
S.push(State(false,v,top.dep+1,top.turn+(kk!=from[top.u]),kk));
}
}
}
}

//rmq
int rmq[2*MAXN][18];//注意要乘以2
void initRMQ()
  {
for(int i=0;i<done;i++)rmq[i][0]=i;
for(int j=1;(1<<j)<=done;j++)
for(int i=0;i+(1<<j)-1<done;i++)
if(B[rmq[i][j-1]]<B[rmq[i+(1<<(j-1))][j-1]])rmq[i][j]=rmq[i][j-1];
else rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
}
inline int RMQ(int a,int b)
  {
int k=0;
while(1<<(k+1)<(b-a+1))k++;
if(B[rmq[a][k]]<B[rmq[b-(1<<k)+1][k]])return F[rmq[a][k]];
return F[rmq[b-(1<<k)+1][k]];
}
inline int LCA(int a,int b)
  {
if(pos[a]<pos[b])return RMQ(pos[a],pos[b]);
return RMQ(pos[b],pos[a]);
}

int main()
  {
scanf("%d%d",&R,&C);
for(int i=0;i<R;i++)
scanf("%s",&rect[i*C]);
for(int i=0;;i++)
 if(rect[i]=='#') {root=i;break;}

done=0;
dfs(root);
initRMQ();
int Q;
scanf("%d",&Q);
while(Q--)
 {
int a,b,c,x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
a=(--x1)*C+(--y1);
b=(--x2)*C+(--y2);
c=LCA(a,b);
int da,db,ka,kb;//da db为到LCA的turn的次数
if(c==a)da=0;
else
 {
da=cost[a]-cost[c];
int i=0;
while(pos[a]>G[c][i].first)i++;
ka=G[c][i].second;
if(from[c]!=ka)da--;//c向上要转的话就-1
}
if(c==b)db=0;
else
 {
db=cost[b]-cost[c];
int i=0;
while(pos[b]>G[c][i].first)i++;
kb=G[c][i].second;
if(from[c]!=kb)db--;
}
printf("%d\n",da+db+ ((c!=a&&c!=b)&&(ka&1)!=(kb&1)) );
}
return 0;
}


|