E. Maze 2D
time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output

The last product of the R2 company in the 2D games' field is a new revolutionary algorithm of searching for the shortest path in a 2 × nmaze.

Imagine a maze that looks like a 2 × n rectangle, divided into unit squares. Each unit square is either an empty cell or an obstacle. In one unit of time, a person can move from an empty cell of the maze to any side-adjacent empty cell. The shortest path problem is formulated as follows. Given two free maze cells, you need to determine the minimum time required to go from one cell to the other.

Unfortunately, the developed algorithm works well for only one request for finding the shortest path, in practice such requests occur quite often. You, as the chief R2 programmer, are commissioned to optimize the algorithm to find the shortest path. Write a program that will effectively respond to multiple requests to find the shortest path in a 2 × n maze.

Input

The first line contains two integers, n and m (1 ≤ n ≤ 2·105; 1 ≤ m ≤ 2·105) — the width of the maze and the number of queries, correspondingly. Next two lines contain the maze. Each line contains n characters, each character equals either '.' (empty cell), or 'X' (obstacle).

Each of the next m lines contains two integers vi and ui (1 ≤ vi, ui ≤ 2n) — the description of the i-th request. Numbers viui mean that you need to print the value of the shortest path from the cell of the maze number vi to the cell number ui. We assume that the cells of the first line of the maze are numbered from 1 to n, from left to right, and the cells of the second line are numbered from n + 1 to 2n from left to right. It is guaranteed that both given cells are empty.

Output

Print m lines. In the i-th line print the answer to the i-th request — either the size of the shortest path or -1, if we can't reach the second cell from the first one.

Sample test(s)
input
4 7
.X..
...X
5 1
1 3
7 7
1 4
6 1
4 7
5 7
output
1
4
0
5
2
2
2
input
10 3
X...X..X..
..X...X..X
11 7
7 18
18 10
output
9
-1
3

这……线段树神题啊

但是这是道馆之战的弱化版……

道馆之战是树上的情况,这题只是一条链的情况

用线段树维护每一个1*2的格子从第一格能不能到第一格、从第一格能不能到第二格、从第二格能不能到第一格、从第二格能不能到第二格

#include<cstdio>
#include<iostream>
#define LL long long
#define inf 0x7ffffff
#define pa pair<int,int>
#define pi 3.1415926535897932384626433832795028841971
using namespace std;
inline LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct segtree{
int l,r;
int a_to_a,a_to_b,b_to_a,b_to_b;
}tree[1000010];
segtree query;
bool mrk[2][200010];
int n,m,x0,y0,x1,y1;
segtree merge(segtree a,segtree b)
{
segtree k;
k.a_to_a=k.a_to_b=k.b_to_a=k.b_to_b=-1;
k.l=min(a.l,b.l); k.r=max(a.r,b.r); if (a.a_to_a!=-1&&b.a_to_a!=-1)k.a_to_a=a.a_to_a+b.a_to_a+1;
if (a.a_to_b!=-1&&b.b_to_a!=-1)
{
if (k.a_to_a==-1)k.a_to_a=a.a_to_b+b.b_to_a+1;
else k.a_to_a=min(k.a_to_a,a.a_to_b+b.b_to_a+1);
} if (a.a_to_a!=-1&&b.a_to_b!=-1)k.a_to_b=a.a_to_a+b.a_to_b+1;
if (a.a_to_b!=-1&&b.b_to_b!=-1)
{
if (k.a_to_b==-1)k.a_to_b=a.a_to_b+b.b_to_b+1;
else k.a_to_b=min(k.a_to_b,a.a_to_b+b.b_to_b+1);
} if (a.b_to_a!=-1&&b.a_to_a!=-1)k.b_to_a=a.b_to_a+b.a_to_a+1;
if (a.b_to_b!=-1&&b.b_to_a!=-1)
{
if (k.b_to_a==-1)k.b_to_a=a.b_to_b+b.b_to_a+1;
else k.b_to_a=min(k.b_to_a,a.b_to_b+b.b_to_a+1);
} if (a.b_to_a!=-1&&b.a_to_b!=-1)k.b_to_b=a.b_to_a+b.a_to_b+1;
if (a.b_to_b!=-1&&b.b_to_b!=-1)
{
if (k.b_to_b==-1)k.b_to_b=a.b_to_b+b.b_to_b+1;
else k.b_to_b=min(k.b_to_b,a.b_to_b+b.b_to_b+1);
}
return k;
}
inline void buildtree(int now,int l,int r)
{
tree[now].l=l;tree[now].r=r;
if (l==r)
{
tree[now].a_to_a=tree[now].a_to_b=tree[now].b_to_a=tree[now].b_to_b=-1;
if (mrk[0][l])tree[now].a_to_a=0;
if (mrk[1][l])tree[now].b_to_b=0;
if (mrk[0][l]&&mrk[1][l])
{
tree[now].a_to_b=1;
tree[now].b_to_a=1;
}
return;
}
int mid=(l+r)>>1;
buildtree(now<<1,l,mid);
buildtree(now<<1|1,mid+1,r);
tree[now]=merge(tree[now<<1],tree[now<<1|1]);
}
inline void work(int now,int x,int y)
{
int l=tree[now].l,r=tree[now].r;
if (l==x&&r==y)
{
if (!query.l)query=tree[now];
else query=merge(query,tree[now]);
return;
}
int mid=(l+r)>>1;
if (y<=mid)work(now<<1,x,y);
else if (x>mid)work(now<<1|1,x,y);
else
{
work(now<<1,x,mid);
work(now<<1|1,mid+1,y);
}
}
inline int ask(int x0,int y0,int x1,int y1)
{
query.l=query.r=0;
work(1,y0,y1);
if (!x0&&!x1)return query.a_to_a;
if (!x0&&x1)return query.a_to_b;
if (x0&&!x1)return query.b_to_a;
if (x0&&x1)return query.b_to_b;
}
int main()
{
n=read();m=read();
for(int i=0;i<=1;i++)
for(int j=1;j<=n;j++)
{
char ch=getchar();while (ch!='X'&&ch!='.')ch=getchar();
if (ch=='.')mrk[i][j]=1;
}
buildtree(1,1,n);
for(int i=1;i<=m;i++)
{
y0=read();y1=read();x0=x1=0;
if ((y0-1)%n+1>(y1-1)%n+1)swap(y0,y1);
if (y0>n){x0=1;y0-=n;}
if (y1>n){x1=1;y1-=n;}
printf("%d\n",ask(x0,y0,x1,y1));
}
}

  

cf413E Maze 2D的更多相关文章

  1. test20181005 迷宫

    题意 分析 时间复杂度里的n,m写反了. 出题人很有举一反三的精神. 代码 我的代码常数巨大,加了各种优化后开O3最慢点都要0.9s. #include<cstdlib> #include ...

  2. CF数据结构练习

    1. CF 438D The Child and Sequence 大意: n元素序列, m个操作: 1,询问区间和. 2,区间对m取模. 3,单点修改 维护最大值, 取模时暴力对所有>m的数取 ...

  3. DFS经典题,reachable or not in a 2D maze

    [[0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 1], [0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 0, 1], [0, 1, 0, 0, 1, 0], ...

  4. LightOJ 1337 F - The Crystal Maze (bfs)

    Description You are in a plane and you are about to be dropped with a parasuit in a crystal maze. As ...

  5. [LeetCode] The Maze III 迷宫之三

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  6. [LeetCode] The Maze II 迷宫之二

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  7. [LeetCode] The Maze 迷宫

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  8. Leetcode: The Maze III(Unsolved Lock Problem)

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  9. Leetcode: The Maze II

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

随机推荐

  1. ios 常用字符串NSString的操作

    //将NSData转化为NSString        NSString* str = [[NSString alloc] initWithData:response encoding:NSUTF8S ...

  2. [MySQL CPU]线上飙升800%,load达到12的解决过程

    接到报警通知,负载过高,达到800%,load也过高,有11了. MySQL版本号为5.6.12-log 1 top 之后,确实是mysqld进程占领了全部资源. 2 查看error日志,无不论什么异 ...

  3. 你的第一Windows程序——管理应用程序状态

    MSDN原文(英文) 管理应用程序状态 一个窗口过程仅仅是一个为每个消息获取调用函数,所以它本质上是无状态的.因此,你需要一个方法来跟踪你的应用程序从一个函数调用下一个函数的状态. 最简单的方法是把一 ...

  4. windows下php+apache+mysql环境搭建

    在Windows 7下进行PHP环境搭建,首先需要下载PHP代码包和Apache与Mysql的安装软件包. PHP版本:php-5.3.2-Win32-VC6-x86,VC9是专门为IIS定制的,VC ...

  5. Linux设备文件自动生成

    第一种是使用mknod手工创建:# mknod <devfilename> <devtype> <major> <minor> 第二种是自动创建设备节点 ...

  6. linux 下文件的比较

    1.cmp命令,比较两个文件是否相同 比较文件test1和test2,如果这两个文件完全相同,则无任何输出,否则,输出第一处不同所在的字节以及行号,然后忽略后面的不同之处,退出命令的执行. [root ...

  7. C#,.net获取字符串中指定字符串的个数、所在位置与替换字符串

    方法一: public static int indexOf (字符串/字符,int从第几位开始,int共查几位) string tests = "1absjjkcbfka2rsbcfak2 ...

  8. javascript sort 用法

    <html> <head> <title></title> <script type="text/javascript" sr ...

  9. 学习Android MediaPlayer

    Android Media Playback 原文 The Android multimedia framework includes support for playing variety of c ...

  10. C#构造函数使用

    作用:帮助我们初始化对像(给对像的每个属性依次的赋值) 构造函数是一个特殊的方法 1.构造函数没有返回值,连void也不能写 2.构造函数名称要和类名一样 3.创建对像时会执行构造函数 4.构造函数可 ...