NOIP analog 929

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]);
    }
}
string

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
*/
home

 

Guess you like

Origin www.cnblogs.com/sto324/p/11620730.html