题解:CF2004D Colored Portals
思路
我们研究颜色,发现最多只有四个不同的颜色,于是跳转时,我们的路程中只要有之前出现过的颜色(除入点),那么就可以省去入点,直接从之前出现过那个颜色的地方跳过来。于是我们得出了一个结论,路程中最多只会经过
考虑起始点
首先考虑它与
如果有
考虑
所以最后选离
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+5;
string ver[]={"BG","BR","BY","GR","GY","RY"};
int las[N][6],nex[N][6],a[N],n,q;
string putin[N];
signed main() {
int tt;cin>>tt;
while(tt--) {
cin>>n>>q;
for(int i=1;i<=n;i++) {
cin>>putin[i];
a[i]=find(ver,ver+6,putin[i])-ver;
}
for(int i=0;i<=n;i++)
for(int j=0;j<6;j++) las[i][j]=-0x3f3f3f3f3f3f3f3f;
for(int i=1;i<=n;i++) {
for(int j=0;j<6;j++) las[i][j]=las[i-1][j];
las[i][a[i]]=i;
}
for(int i=1;i<=n+1;i++)
for(int j=0;j<6;j++) nex[i][j]=0x3f3f3f3f3f3f3f3f;
for(int i=n;i>=1;i--) {
for(int j=0;j<6;j++) nex[i][j]=nex[i+1][j];
nex[i][a[i]]=i;
}
while(q--) {
int x,y;cin>>x>>y;
bool flag=0;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
if(putin[x][i]==putin[y][j]) {
flag=1;
goto ok;
}
ok:
if(flag) {
cout<<abs(y-x)<<endl;
continue;
}
int minn=1e9;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++) {
char xx=putin[x][i],yy=putin[y][j];
if(xx>yy) swap(xx,yy);
string s;s+=xx;s+=yy;
int value=find(ver,ver+6,s)-ver;
minn=min(minn,abs(x-las[x][value])+abs(y-las[x][value]));
minn=min(minn,abs(x-nex[x][value])+abs(y-nex[x][value]));
}
cout<<(minn==(int)1000000000?-1:minn)<<endl;
}
}
return 0;
}