传送门:【CodeForces】471D MUH and Cube Walls
题目分析:很容易想到KMP,然后可以进一步的想到如果轮廓能匹配,也就意味着相邻两个匹配的主串 减 模式串的值相同即可匹配。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep( i , a , b ) for ( int i = ( a ) ;i < ( b ) ;++ i )
#define rev( i , a , b ) for ( int i = ( a ) ;i >= ( b ) ;-- i )
#define For( i , a , b ) for ( int i = ( a ) ;i <= ( b ) ;++ i )
#define clr( a , x ) memset ( a , x , sizeof a )
typedef long long LL ;
const int MAXN = 200005 ;
int s[MAXN] ;
int p[MAXN] ;
int next[MAXN] ;
int n , m ;
int cmp ( int i , int j , int a[] , int b[] ) {
if ( j == 1 ) return 1 ;
return a[i] - b[j] == a[i - 1] - b[j - 1] ;
}
void get_next () {
next[1] = 0 ;
int j = 0 ;
For ( i , 2 , m ) {
while ( j && !cmp ( i , j + 1 , p , p ) ) j = next[j] ;
if ( cmp ( i , j + 1 , p , p ) ) ++ j ;
next[i] = j ;
}
}
void get_kmp () {
int ans = 0 ;
int j = 0 ;
For ( i , 1 , n ) {
while ( j && !cmp ( i , j + 1 , s , p ) ) j = next[j] ;
if ( cmp ( i , j + 1 , s , p ) ) {
++ j ;
if ( j == m ) {
++ ans ;
//printf ( "%d\n" , i ) ;
j = next[j] ;
}
} else j = next[j] ;
//printf ( "%d\n" , j ) ;
}
printf ( "%d\n" , ans ) ;
}
void solve () {
For ( i , 1 , n ) scanf ( "%d" , &s[i] ) ;
For ( i , 1 , m ) scanf ( "%d" , &p[i] ) ;
get_next () ;
get_kmp () ;
}
int main () {
while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
return 0 ;
}