Description
Wells来到了一个未知的梦幻国度,这个国度有 2N 个城市,分布为一个 2*N 的矩阵。有些城市是无法到达的。一个城市可以到达与之曼哈顿距离为 1 的城市。
![](/upload/problem_attach/2018-03-31_21D8BE176B268C86/xtravelplan.png.pagespeed.ic.MLsHZH7qBI.webp)
大家都知道打acm没有太多的自由时间出去玩,但Wells仍然想知道,如果在从第 l 个城市出发到第 r 个城市的最少需要经过多少城市。
城市的分布如下图:
1, 2, 3, ….N
N+1,N+2,N+3….N*2
Input
第一行两个正整数 n,m,m 为询问数 接下来两行,每行是一个长度为 N 的字符串,表示城市能否经过。 若为 X,表示不能经过,若为 P,表示可以经过。 接下来 m 行,每行两个整数 l,r,描述一个询问。
Output
对于每个询问输出一行,l 到 r 的需要经过的最少城市个数(不包括起点,但包括终点),若无法到达输出-1。
Sample Input
3 4 XPX PPP 1 4 4 2 6 5 6 4
Sample Output
-1 2 1 2
Hint
对于所有数据,n, m < =2 * 105.
Source
Author
Wells
#include <iostream>
#include <string>
#include <cstdio>
#include <math.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int MAX=2e5+10;
int dis[MAX][20][2][2];
int base[20];
int n,m;
char a[MAX];
char b[MAX];
void init() {
memset(dis,0x3f,sizeof dis);
base[0]=1;
for(int i=1; i<20; i++) {
base[i]=base[i-1]*2;
}
for(int i=0; i<n; i++) {
/// 上到上
if(a[i+1]=='P' && a[i]=='P') {
dis[i][0][0][0]=1;
}
/// 上到下
if(a[i]=='P'&&b[i+1]=='P' &&(b[i]=='P'||a[i+1]=='P')) {
dis[i][0][0][1]=2;
}
/// 下到上
if(b[i]=='P' &&a[i+1]=='P' &&(a[i]=='P' ||b[i+1]=='P')) {
dis[i][0][1][0]=2;
}
/// 下到下
if(b[i+1]=='P'&& b[i]=='P') {
dis[i][0][1][1]=1;
}
}
for(int k=1; k<20; k++) {
for(int i=0; i<n; i++) {
if(i+base[k]>=n) break;
int cnt=1e9;
/// 上到上
if(dis[i][k-1][0][0]<2*MAX && dis[i+base[k-1]][k-1][0][0]<2*MAX && a[i+base[k-1]]=='P' && a[i]=='P') {
cnt=min(cnt,dis[i][k-1][0][0]+dis[i+base[k-1]][k-1][0][0]);
}
if(dis[i][k-1][0][1]<2*MAX && dis[i+base[k-1]][k-1][1][0]<2*MAX && b[i+base[k-1]]=='P' && a[i]=='P') {
cnt=min(cnt,dis[i][k-1][0][1]+dis[i+base[k-1]][k-1][1][0]);
}
dis[i][k][0][0]=cnt;
/// 上到下
cnt=1e9;
if(dis[i][k-1][0][1]<2*MAX && dis[i+base[k-1]][k-1][1][1]<2*MAX && b[i+base[k-1]]=='P'&& a[i]=='P') {
cnt=min(cnt,dis[i][k-1][0][1]+dis[i+base[k-1]][k-1][1][1]);
}
if(dis[i][k-1][0][0]<2*MAX && dis[i+base[k-1]][k-1][0][1]<2*MAX && a[i+base[k-1]]=='P'&& a[i]=='P') {
cnt=min(cnt,dis[i][k-1][0][0]+dis[i+base[k-1]][k-1][0][1]);
}
dis[i][k][0][1]=cnt;
/// 下到上
cnt=1e9;
if(dis[i][k-1][1][0]<2*MAX && dis[i+base[k-1]][k-1][0][0]<2*MAX && a[i+base[k-1]]=='P' && b[i]=='P') {
cnt=min(cnt,dis[i][k-1][1][0]+dis[i+base[k-1]][k-1][0][0]);
}
if(dis[i][k-1][1][1]<2*MAX && dis[i+base[k-1]][k-1][1][0]<2*MAX && b[i+base[k-1]]=='P' && b[i]=='P') {
cnt=min(cnt,dis[i][k-1][1][1]+dis[i+base[k-1]][k-1][1][0]);
}
dis[i][k][1][0]=cnt;
/// 下到下
cnt=1e9;
if(dis[i][k-1][1][1]<2*MAX && dis[i+base[k-1]][k-1][1][1]<2*MAX && b[i+base[k-1]]=='P' && b[i]=='P') {
cnt=min(cnt,dis[i][k-1][1][1]+dis[i+base[k-1]][k-1][1][1]);
}
if(dis[i][k-1][1][0]<2*MAX && dis[i+base[k-1]][k-1][0][1]<2*MAX && a[i+base[k-1]]=='P' && b[i]=='P') {
cnt=min(cnt,dis[i][k-1][1][0]+dis[i+base[k-1]][k-1][0][1]);
}
dis[i][k][1][1]=cnt;
}
}
}
int dp[20][2];
int main() {
while(cin>>n>>m){
scanf("%s",a);
scanf("%s",b);
init();
for(int i=0; i<m; i++) {
memset(dp,0x3f,sizeof dp);
int l,r;
scanf("%d %d",&l,&r);
int cntl=l,cntr=r;
if(cntl>n) cntl-=n;
if(cntr>n) cntr-=n;
cntl--,cntr--;
if(cntl>cntr){
swap(cntl,cntr);
swap(l,r);
}
if(cntl==cntr){
int flag=1;
if(l>n) flag&= (b[cntl]=='P');
else flag &= (a[cntl]=='P');
if(r>n) flag &= (b[cntl]=='P');
else flag &= (a[cntl]=='P');
if(!flag){
puts("-1");
}else{
if(l==r)
puts("0");
else{
puts("1");
}
}
}else{
cntr-=cntl;
int tot=0;
int flagl=l>n,flagr=r>n;
if(flagl) {
dp[0][1]=0;
} else {
dp[0][0]=0;
}
for(int i=19; i>=0; i--) {
if(cntr>=base[i]) {
tot++;
dp[tot][0]=min(dp[tot-1][0]+dis[cntl][i][0][0],dp[tot-1][1]+dis[cntl][i][1][0]);
dp[tot][1]=min(dp[tot-1][0]+dis[cntl][i][0][1],dp[tot-1][1]+dis[cntl][i][1][1]);
cntr-=base[i],cntl+=base[i];
}
}
printf("%d\n",((dp[tot][flagr]>3*MAX||dp[tot][flagr]<0)?-1:dp[tot][flagr]));
}
}
}
return 0;
}