codeforce 906 SOL (E)
我们可以把S与T每隔一位插入,构成一个新串A
for (int i=1;i<=n;i++) A[++tot]=s[i],A[++tot]=t[i];
首先,我们发现题目告诉我们旋转非交,那么事情就很好办了。
T中的字母有两种状态,一种是未翻转,一种是翻转,不翻转的S与T在这一位上一模一样,我们不去管它。
至于翻转的,就是一个回文串。
那么我们PAM(回文自动机)跑起来,成功滑稽。不会PAM的同学点这里
#include<bits/stdc++.h> #define inf (1<<27) using namespace std; #define N 1007001 int tot,len[N],fa[N],net[N][26],slink[N],df[N],w,p,last; int newq,q,n,ans[N],_a[N],fr[N]; char A[N],t[N],s[N]; void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } void extend(int x){ w=A[x]-'a',p=last; while (A[x]^A[x-len[p]-1]) p=fa[p]; if (!net[p][w]) { q=++tot; len[q]=len[p]+2; newq=p; do newq=fa[newq]; while (A[x]^A[x-len[newq]-1]); fa[q]=net[newq][w]; net[p][w]=q; df[q]=len[q]-len[fa[q]]; slink[q]=(df[q]==df[fa[q]]?slink[fa[q]]:fa[q]); } last=net[p][w]; } int main () { freopen("e.in","r",stdin); scanf("%s%s",s+1,t+1); n=strlen(s+1); for (int i=1;i<=n;i++) A[++tot]=s[i],A[++tot]=t[i]; n<<=1; fa[0]=tot=1; len[1]=-1; memset(ans,127,sizeof ans); ans[0]=0; _a[0]=1; for (int i=1;i<=n;i++) { extend(i); for (p=last;p;p=slink[p]){ _a[p]=i-(len[slink[p]]+df[p]); if (df[fa[p]]==df[p]&&ans[_a[p]]>ans[_a[fa[p]]]) _a[p]=_a[fa[p]]; if (!(i&1)&&ans[i]>ans[_a[p]]+1) ans[i]=ans[_a[p]]+1,fr[i]=_a[p]; } if (!(i&1)&&A[i]==A[i-1]&&ans[i]>ans[i-2]) ans[i]=ans[i-2],fr[i]=i-2; } if (ans[n]>inf) {puts("-1"); return 0;} writeln(ans[n]); for (int i=n;i;i=fr[i]) if (i-fr[i]>2) writel(fr[i]+2>>1),writeln(i>>1); return 0; }