XJOI网上同步测试DAY14 T1
思路:线段树维护最短路
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> struct node{ int l,r,c[3][3]; }t[1000005]; int id[3][400005]; int s[3][400005]; int fa[400005],n; int read(){ int t=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f; } int find(int x){ if (fa[x]==x) return x; else return fa[x]=find(fa[x]); } node operator +(node a,node b){ node p; p.l=std::min(a.l,b.l); p.r=std::max(a.r,b.r); p.c[0][0]=p.c[1][1]=p.c[0][1]=p.c[1][0]=0x3f3f3f3f; for (int i=0;i<=1;i++) if (s[i][a.l]==0) for (int j=0;j<=1;j++) if (s[j][b.r]==0) for (int k=0;k<=1;k++) if (s[k][a.r]==0&&s[k][b.l]==0) p.c[i][j]=std::min(p.c[i][j],a.c[i][k]+b.c[k][j]+1); return p; } void build(int k,int l,int r){ t[k].c[0][0]=t[k].c[1][1]=t[k].c[1][0]=t[k].c[0][1]=0x3f3f3f3f; if (l==r){ t[k].l=t[k].r=l; if (s[0][l]==0) t[k].c[0][0]=0; if (s[1][l]==0) t[k].c[1][1]=0; if (s[0][l]==0&&s[1][l]==0) t[k].c[0][1]=t[k].c[1][0]=1; return; } int mid=(l+r)>>1; build(k*2,l,mid); build(k*2+1,mid+1,r); t[k]=t[k*2]+t[k*2+1]; } void init(){ char S[400005]; scanf("%s",S+1); for (int i=1;i<=n;i++) s[0][i]=S[i]-'0'; scanf("%s",S+1); for (int i=1;i<=n;i++) s[1][i]=S[i]-'0'; int sz=0; for (int i=0;i<2;i++) for (int j=1;j<=n;j++) id[i][j]=++sz; for (int i=1;i<=2*n;i++) fa[i]=i; for (int i=1;i<n;i++) if (s[0][i]==0&&s[0][i+1]==0) fa[find(id[0][i])]=find(id[0][i+1]); for (int i=1;i<n;i++) if (s[1][i]==0&&s[1][i+1]==0) fa[find(id[1][i])]=find(id[1][i+1]); for (int i=1;i<=n;i++) if (s[0][i]==0&&s[1][i]==0) fa[find(id[1][i])]=find(id[0][i]); } node query(int k,int l,int r,int x,int y){ int mid=(l+r)>>1; node tmp; if (l==x&&r==y) return t[k]; if (y<=mid) return query(k*2,l,mid,x,y); else if (x>mid) return query(k*2+1,mid+1,r,x,y); else return query(k*2,l,mid,x,mid)+query(k*2+1,mid+1,r,mid+1,y); } int main(){ int T; n=read();T=read(); init(); build(1,1,n); while (T--){ int x=read(),y=read(); if (x==y) {puts("0");continue;} if (find(x)!=find(y)){puts("You have been confusional!");continue;} int x1=(x>n)?x-n:x;int y1=(y>n)?y-n:y; if (x1>y1) std::swap(x,y),std::swap(x1,y1); node tmp=query(1,1,n,x1,y1); int id1,id2; if (x>n) id1=1;else id1=0; if (y>n) id2=1;else id2=0; int ans=tmp.c[id1][id2]; if (ans==0x3f3f3f3f) puts("You have been confusional!"); else printf("%d\n",ans); } }