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('
'); }
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;
}
原文地址:https://www.cnblogs.com/rrsb/p/8298431.html