D

D. MUH and Cube Walls
 

Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev got hold of lots of wooden cubes somewhere. They started making cube towers by placing the cubes one on top of the other. They defined multiple towers standing in a line as a wall. A wall can consist of towers of different heights.

Horace was the first to finish making his wall. He called his wall an elephant. The wall consists of w towers. The bears also finished making their wall but they didn't give it a name. Their wall consists of n towers. Horace looked at the bears' tower and wondered: in how many parts of the wall can he "see an elephant"? He can "see an elephant" on a segment of w contiguous towers if the heights of the towers on the segment match as a sequence the heights of the towers in Horace's wall. In order to see as many elephants as possible, Horace can raise and lower his wall. He even can lower the wall below the ground level (see the pictures to the samples for clarification).

Your task is to count the number of segments where Horace can "see an elephant".

Input

The first line contains two integers n and w (1 ≤ n, w ≤ 2·105) — the number of towers in the bears' and the elephant's walls correspondingly. The second line contains n integers ai (1 ≤ ai ≤ 109) — the heights of the towers in the bears' wall. The third line contains w integers bi (1 ≤ bi ≤ 109) — the heights of the towers in the elephant's wall.

Output

Print the number of segments in the bears' wall where Horace can "see an elephant".

Sample test(s)
input
13 5
2 4 5 5 4 3 2 2 2 3 3 2 1
3 4 4 3 2
output
2
Note

The picture to the left shows Horace's wall from the sample, the picture to the right shows the bears' wall. The segments where Horace can "see an elephant" are in gray.

#include <bits/stdc++.h>
using namespace std;
void makeNext(const int P[],int next[],int m)
{
    /*
    next[i]表示前i个字符中,最大前后缀相同的长度
    */
    int q,k;
    next[0]=0;
    for (q=1,k=0;q<m;++q)
    {
        while(k>0&&P[q]!=P[k])
            k = next[k-1];
        /*
        这里的while循环很不好理解!
        就是用一个循环来求出前后缀最大公共长度;
        首先比较P[q]和P[K]是否相等如果相等的话说明已经K的数值就是已匹配到的长的;
        如果不相等的话,那么next[k-1]与P[q]的长度,为什么呐?因为当前长度不合适
        了,不能增长模板链,就缩小看看next[k-1]
        的长度能够不能和P[q]匹配,这么一直递归下去直到找到
        */
        if(P[q]==P[k])//如果当前位置也能匹配上,那么长度可以+1
        {
            k++;
        }
        next[q]=k;
    }
}

int kmp(const int T[],const int P[],int next[],int n,int m)
{
    int i,q;
    makeNext(P,next,m);
    int res=0;
    for (i=0,q=0;i<n;++i)
    {
        while(q>0&&P[q]!= T[i])
            q = next[q-1];
        /*
        这里的循环就是位移之后P的前几个字符能个T模板匹配
        */
        if(P[q]==T[i])
        {
            q++;
        }
        if(q==m)//如果能匹配的长度刚好是T的长度那么就是找到了一个能匹配成功的位置
        {
            res++;
        }
    }
    return res;
}
int T[200005];
int P[200005];
int next[200005];
int n,m;
int main(){
    // freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&T[i]);
    }
    for(int i=0;i<m;i++){
        scanf("%d",&P[i]);
    }
    for(int i=0;i<n-1;i++){
        T[i]=T[i+1]-T[i];
    }
    n--;
    for(int i=0;i<m-1;i++){
        P[i]=P[i+1]-P[i];
    }
    m--;
    if(m==0){
        printf("%d
",n+1);
        return 0;
    }
    if(n==0){
        printf("0
");
        return 0;
    }
    makeNext(P,next,m);
    printf("%d
",kmp(T,P,next,n,m));
    return 0;
}
原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6701647.html