CF906EReverses(回文自动机,最小回文分割)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF906EReverses(回文自动机,最小回文分割)相关的知识,希望对你有一定的参考价值。
题意:给定两个长度相等的仅由小写字母组成的串A和B,问在A中最少选择多少段互不相交的子串进行翻转能使A和B相同
len<=5e5
思路:构造新串S=a[1]b[1]a[2]b[2]...a[n]b[n]
问题等价于求S的最小回文分割,其中需要每一段的长度都为偶数,注意长度为2的相当于没有翻转
把板子稍加修改即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,int>P; 11 #define N 1100010 12 #define M 210000 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 26 const int MOD=998244353,inv2=(MOD+1)/2; 27 double eps=1e-6; 28 int INF=1<<29; 29 ll inf=5e13; 30 int dx[4]=-1,1,0,0; 31 int dy[4]=0,0,-1,1; 32 33 34 char a[N],b[N]; 35 int s[N]; 36 int n; 37 int q,p,id,num[N],F[N],f[N],_f[N],pre[N],len[N],sk[N],df[N],t[N][26]; 38 39 struct pam 40 41 void add(int x,int n) 42 43 while(s[n-len[p]-1]!=s[n]) p=F[p]; 44 if(!t[p][x]) 45 46 int q=++id,k=F[p]; 47 len[q]=len[p]+2; 48 while(s[n-len[k]-1]!=s[n]) k=F[k]; 49 F[q]=t[k][x]; 50 t[p][x]=q; 51 df[q]=len[q]-len[F[q]]; 52 sk[q]=(df[q]==df[F[q]]?sk[F[q]]:F[q]); 53 54 p=t[p][x]; 55 56 pam; 57 58 int read() 59 60 int v=0,f=1; 61 char c=getchar(); 62 while(c<48||57<c) if(c==‘-‘) f=-1; c=getchar(); 63 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 64 return v*f; 65 66 67 int main() 68 69 //freopen("1.in","r",stdin); 70 //freopen("1.out","w",stdout); 71 scanf("%s",a+1); 72 int m=strlen(a+1); 73 scanf("%s",b+1); 74 int n=0; 75 rep(i,1,m) 76 77 s[++n]=a[i]-‘a‘; 78 s[++n]=b[i]-‘a‘; 79 80 s[n+1]=s[0]=100; 81 id=F[0]=1; len[1]=-1; _f[0]=1; 82 rep(i,1,n) f[i]=1e9; 83 rep(i,1,n) 84 85 pam.add(s[i],i); 86 for(int x=p;x;x=sk[x]) 87 88 _f[x]=i-len[sk[x]]-df[x]; 89 if(df[F[x]]==df[x]&&f[_f[x]]>f[_f[F[x]]]) _f[x]=_f[F[x]]; 90 if(i%2==0&&f[i]>f[_f[x]]+1) f[i]=f[_f[x]]+1,pre[i]=_f[x]; 91 if(i%2==0&&s[i]==s[i-1]&&f[i-2]<f[i]) 92 93 f[i]=f[i-2]; 94 pre[i]=i-2; 95 96 97 98 //rep(i,1,n) printf("%d ",s[i]); 99 //printf("\n"); 100 if(f[n]==1e9) 101 102 printf("-1\n"); 103 return 0; 104 105 printf("%d\n",f[n]); 106 int k=n; 107 while(k) 108 109 int t=pre[k]; 110 if(t<k-2) printf("%d %d\n",t/2+1,k/2); 111 k=t; 112 113 114 return 0; 115
以上是关于CF906EReverses(回文自动机,最小回文分割)的主要内容,如果未能解决你的问题,请参考以下文章
CF17E Palisection(manacher/回文树)