match
There are two strings A, B, A wherein B is a length of $ l_ {B} $ prefix, now fill characters to the end B, the maximum prefix solving A suffix B is equal to
$ T <= 10, l_ {B} <= 100000, l_ {B} <= l_ {A} <= 2 * l_ {B} $, all lowercase letters are
answer
In addition to taking into account the last character is the prefix A, so the prefix B after conversion if B is not A, then B is seeking maximum prefix equal to the suffix.
With kmp on the line
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=200005; int T,lena,lenb; char c[2],s[maxn],t[maxn]; int fail[maxn]; void kmp(){ fail[0]=fail[1]=0; for(int i=1;i<lenb;i++){ int t=fail[i]; while(t&&s[i]!=s[t]) t=fail[t]; fail[i+1]=(s[i]==s[t] ? t+1 : 0); } } int main(){ freopen("string.in","r",stdin); freopen("string.out","w",stdout); scanf("%d",&T); while(T--){ scanf("%d%d%s%s",&lena,&lenb,s,c); if(s[lenb]==c[0]) {printf("%d\n",lenb+1);continue;} s[lenb++]=c[0]; kmp(); printf("%d\n",fail[lenb]); } }
Come back home
FIG n has a point m edges, will seek through point from 1 to n.
m <= 2n, n <= 200000, a plurality of sets of data
answer
Give a wrong idea: consider a necessary point must be cut point, must pass through a certain point in the shortest way. So, after tarjan determined cut points, find the shortest run twice bfs, the final judgment.
Why is it wrong? Because these are just nature, and can not draw conclusions.
The most important is the cut point can not be guaranteed and n are not communicating 1
Therefore, in consideration of whether the subtree n, can be determined at the time of recording of tarjan.
Details in code comments
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=200005; const int inf=0x3f3f3f; int t,n,m,cur,cnt; int head[maxn]; int dfn[maxn],low[maxn]; int top,sta[maxn]; bool cut[maxn],con[maxn]; int dis[maxn][2]; struct edge{ int x,y,next; }e[maxn<<3]; template<class T>inline void read(T &x){ x=0;int f=0;char ch=getchar(); while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x = f ? -x : x ; } void add(int x,int y){ e[++cnt]=(edge){x,y,head[x]}; head[x]=cnt; } void init(){ cnt=top=cur=0; memset(cut,false,sizeof(cut)); memset(con,false,sizeof(con)); memset(head,0,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); for(int i=1;i<=n;i++) dis[i][0]=dis[i][1]=inf; } void tarjan(int x,int fa){ int num=0;if(x==n) con[x]=true; low[x]=dfn[x]=++cur; for(int i=head[x];i;i=e[i].next){ int y=e[i].y; if(!dfn[y]){ tarjan(y,x); low[x]=min(low[x],low[y]); con[x]|=con[y]; IF(dfn [x] <= low [ y] && CON [y]) // Analyzing con [y]: When because dfn [x] <= low [ y] know when the cut point 3.10 y subtree, if x final judgment result in separate subtrees contain n- Cut [x] = to true ; } the else IF (! Y = FA) Low [x] = min (Low [x], DFN [Y]); } } void Solve () { Read (n-); Read (m); the init (); for ( int I = . 1 ; I <= m; I ++ ) { int X, Y; Read (X); Read (Y); IF (X Y ==) Continue ; the Add (X, Y); the Add (Y, X); } Tarjan ( . 1 , 0 ); for(int i=2;i<n;i++) if(cut[i]) sta[++top]=i; printf("%d\n",top); for(int i=1;i<=top;i++) printf("%d ",sta[i]); putchar(10); } int main(){ freopen("home.in","r",stdin); freopen("home.out","w",stdout); read(t); while(t--)solve(); } /* 2 4 3 1 2 2 3 3 4 5 5 1 2 2 3 3 4 4 5 4 1 */