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 }

 

posted @ 2018-11-03 19:52  *zzq  阅读(291)  评论(0编辑  收藏  举报