题意:给定两个长度相等的仅由小写字母组成的串A和B,问在A中最少选择多少段互不相交的子串进行翻转能使A和B相同
len<=5e5
思路:构造新串S=a[1]b[1]a[2]b[2]...a[n]b[n]
问题等价于求S的最小回文分割,其中需要每一段的长度都为偶数,注意长度为2的相当于没有翻转
把板子稍加修改即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,int>P;
#define N 1100010
#define M 210000
#define fi first
#define se second
#define MP make_pair
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const int MOD=,inv2=(MOD+)/;
double eps=1e-;
int INF=<<;
ll inf=5e13;
int dx[]={-,,,};
int dy[]={,,-,}; char a[N],b[N];
int s[N];
int n;
int q,p,id,num[N],F[N],f[N],_f[N],pre[N],len[N],sk[N],df[N],t[N][]; struct pam
{
void add(int x,int n)
{
while(s[n-len[p]-]!=s[n]) p=F[p];
if(!t[p][x])
{
int q=++id,k=F[p];
len[q]=len[p]+;
while(s[n-len[k]-]!=s[n]) k=F[k];
F[q]=t[k][x];
t[p][x]=q;
df[q]=len[q]-len[F[q]];
sk[q]=(df[q]==df[F[q]]?sk[F[q]]:F[q]);
}
p=t[p][x];
}
}pam; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%s",a+);
int m=strlen(a+);
scanf("%s",b+);
int n=;
rep(i,,m)
{
s[++n]=a[i]-'a';
s[++n]=b[i]-'a';
}
s[n+]=s[]=;
id=F[]=; len[]=-; _f[]=;
rep(i,,n) f[i]=1e9;
rep(i,,n)
{
pam.add(s[i],i);
for(int x=p;x;x=sk[x])
{
_f[x]=i-len[sk[x]]-df[x];
if(df[F[x]]==df[x]&&f[_f[x]]>f[_f[F[x]]]) _f[x]=_f[F[x]];
if(i%==&&f[i]>f[_f[x]]+) f[i]=f[_f[x]]+,pre[i]=_f[x];
if(i%==&&s[i]==s[i-]&&f[i-]<f[i])
{
f[i]=f[i-];
pre[i]=i-;
}
}
}
//rep(i,1,n) printf("%d ",s[i]);
//printf("\n");
if(f[n]==1e9)
{
printf("-1\n");
return ;
}
printf("%d\n",f[n]);
int k=n;
while(k)
{
int t=pre[k];
if(t<k-) printf("%d %d\n",t/+,k/);
k=t;
} return ;
}