CF-413E-线段树
http://codeforces.com/problemset/problem/413/E
给出一个2*N的格子图,每个格子要么是障碍要么是空地,M次询问(A,B)之间的最短距离。
采用分治的思想,由于只有两行,那么对于任意两列,起点和终点的组合方式只有四种,令d[i][]表示第i个节点对应的区间内,左上-右上,左下-右下,左上-右下,左下-右上的最短路,询问的时候也返回
一个一维数组就好了,对应四种不同的走向。
zb的写了个LL*返回结果调试半天,发现指向的是一片临时区域,函数结束时销毁了这片内存所以值在中间就没了= =。换了new就好了。
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<map> 6 #include<set> 7 #include<vector> 8 using namespace std; 9 #define LL long long 10 #define ULL unsigned long long 11 #define pii pair<int,int> 12 #define mid ((L+R)>>1) 13 #define lc (id<<1) 14 #define rc (id<<1|1) 15 #define pb push_back 16 #define mp make_pair 17 #define inf 500000 18 #define linf 0xffffffffffff 19 const int maxn=200020; 20 char e[2][maxn]; 21 LL d[maxn<<2][4]; 22 void build(int id,int L,int R){ 23 if(L==R){ 24 d[id][0]=e[0][L]=='X'?inf:0; 25 d[id][1]=e[1][L]=='X'?inf:0; 26 d[id][2]=e[1][L]=='X'||e[0][L]=='X'?inf:1; 27 d[id][3]=e[0][L]=='X'||e[1][L]=='X'?inf:1; 28 } 29 else{ 30 build(lc,L,mid); 31 build(rc,mid+1,R); 32 { 33 d[id][0]=1+min(d[lc][0]+d[rc][0],d[lc][2]+d[rc][3]); 34 d[id][1]=1+min(d[lc][1]+d[rc][1],d[lc][3]+d[rc][2]); 35 d[id][2]=1+min(d[lc][0]+d[rc][2],d[lc][2]+d[rc][1]); 36 d[id][3]=1+min(d[lc][1]+d[rc][3],d[lc][3]+d[rc][0]); 37 } 38 } 39 } 40 int tot=0; 41 LL* ask(int id,int L,int R,int l,int r){ 42 if(L>=l&&R<=r){ 43 return d[id]; 44 } 45 if(r<=mid){ 46 return ask(lc,L,mid,l,r); 47 } 48 else if(l>mid){ 49 return ask(rc,mid+1,R,l,r); 50 } 51 else{ 52 LL *p=ask(lc,L,mid,l,r),*q=ask(rc,mid+1,R,l,r); 53 LL *ret=new LL[4]; 54 { 55 ret[0]=1+min(p[0]+q[0],p[2]+q[3]); 56 ret[1]=1+min(p[1]+q[1],p[3]+q[2]); 57 ret[2]=1+min(p[0]+q[2],p[2]+q[1]); 58 ret[3]=1+min(p[1]+q[3],p[3]+q[0]); 59 } 60 return ret; 61 } 62 } 63 int main() 64 { 65 int u,v,N,M,i; 66 scanf("%d%d",&N,&M); 67 scanf("%s %s",e[0]+1,e[1]+1); 68 build(1,1,N); 69 while(M--){ 70 scanf("%d%d",&u,&v); 71 int _u=(u-1)%N+1,_v=(v-1)%N+1; 72 if(_u>_v)swap(_u,_v),swap(u,v); 73 LL *ans; 74 ans=ask(1,1,N,_u,_v); 75 if(u<=N&&v<=N&&ans[0]<inf){ 76 printf("%lld\n",ans[0]); 77 } 78 else if(u>N&&v>N&&ans[1]<inf){ 79 printf("%lld\n",ans[1]); 80 } 81 else if(u<=N&&v>N&&ans[2]<inf){ 82 printf("%lld\n",ans[2]); 83 } 84 else if(u>N&&v<=N&&ans[3]<inf){ 85 printf("%lld\n",ans[3]); 86 } 87 else{ 88 puts("-1"); 89 } 90 } 91 return 0; 92 }