// codeforces 471D // kmp初学

// codeforces 471D //
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int n,w;
int a[200005],b[200005];
int da[200005],db[200005];
int next[200005];
void kmp()
{
    next[1]=0;
    for(int i=1;i<w-1;i++)
    {
        int k=next[i];
        while(k!=0)
        {
            if(db[i+1]==db[k+1])
            {
                next[i+1]=k+1;
                break;
            }
            k=next[k];
        }
        if(k==0)
        {
            next[i+1] = (db[i+1]==db[1] ? 1 : 0);
        }
    }
}
int query()
{
    int p=0,res=0;
    for(int i=1;i<n;i++)
    {
        while(da[i]!=db[p+1] && p!=0)
        {
            p=next[p];
        }
        if(da[i]==db[p+1])
        {
            p++;
        }
        if(p==w-1)
        {
            res++;
            p=next[p];
        }
    }
    return res;
}
int main()
{
    scanf("%d%d",&n,&w);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=w;i++)
    {
        scanf("%d",&b[i]);
    }
    if(w==1)printf("%d\n",n);
    else
    {
        for(int i=1;i<n;i++)
        {
            da[i]=a[i+1]-a[i];
        }
        for(int i=1;i<w;i++)
        {
            db[i]=b[i+1]-b[i];
        }
        kmp();
        printf("%d\n",query());
    }
    return 0;
}
时间: 2025-01-10 14:07:32

// codeforces 471D // kmp初学的相关文章

CodeForces - 471D MUH and Cube Walls

CodeForces - 471D 记录差分,利用kmp对分别除去了第一个数的两个数组进行匹配 注意特判模式串长度为一的情况 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int maxn = 2e5 + 10; 6 int ans, n, m; 7 8 void find_substring(int pattern[], int text[]) { 9 vector<int

Codeforces 471D 差分+kmp

题意 给出两个长度为n,m的a,b序列 问n中有多少个连续长度为m的序列,同时加/减去某一个数后和b相同 c序列同时加上/减去某个数,其相邻差不变. 算出相邻差,跑一遍kmp即可 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e6+20; int n,m,a[N],b[N],c[N],d[N]; int fail[N]; void getfail() { int i=0,j=-1

KMP初学

时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一只河蟹,于是河蟹就向小Hi和小Ho提出了那个经典的问题:"小Hi和小Ho,你们能不能够判断一段文字(原串)里面是不是存在那么一些--特殊--的文字(模式串)?" 小Hi和小Ho仔细思考了一下,觉得只能想到很简单的做法,但是又觉得既然河蟹先生这么说了,就肯定不会这么容易的

【CodeForces】471D MUH and Cube Walls KMP或者字符串HASH

想到两点就行: 1.相邻项相减,处理出相对高度,这样如果pattern或者text增加的话,就没问题了 2.KMP匹配O(n) HASH的话 ,我WA在第25组数据了,听说如果改为大素数取模就能AC KMP AC了 但是好奇怪我的KMP模板难道有问题?? 先贴KMP ac 代码 //#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring>

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

codeforces 825F F. String Compression dp+kmp找字符串的最小循环节

/** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: dp[i]表示前i个字符需要的最小次数. dp[i] = min(dp[j]+w(j+1,i)); (0<=j<i); [j+1,i]如果存在循环节(自身不算),那么取最小的循环节x.w = digit((i-j)/x)+x; 否则w = i-j+1; 求一个区间最小循环节: 证明:http://w

Codeforces 432D Prefixes and Suffixes(KMP+dp)

题目连接:Codeforces 432D Prefixes and Suffixes 题目大意:给出一个字符串,求全部既是前缀串又是后缀串的字符串出现了几次. 解题思路:依据性质能够依据KMP算法求出全部的前后缀串,然后利用dp求解,dp[i]表示从1到i这个子串出现过的次数.转移方程dp[jump[i]]+=dp[i].随意一个dp[i]的初始状态应该是1. #include <cstdio> #include <cstring> const int N = 1e5+5; int

Educational Codeforces Round 25 F. String Compression(kmp+dp)

题目链接:Educational Codeforces Round 25 F. String Compression 题意: 给你一个字符串,让你压缩,问压缩后最小的长度是多少. 压缩的形式为x(...)x(...)  x表示(...)这个出现的次数. 题解: 考虑dp[i]表示前i个字符压缩后的最小长度. 转移方程解释看代码,这里要用到kmp来找最小的循环节. 当然还有一种找循环节的方式就是预处理lcp,然后通过枚举循环节的方式. 这里我用的kmp找的循环节.复杂度严格n2. 1 #inclu

CodeForces 25E Test KMP

题目链接:点击打开链接 题意: 给定3个字符串,进行拼接 重复的一段可以覆盖,问拼接后最小的长度(若一个串s1是s2的子串,则s1可以认为嵌入了s2内,不需要进行拼接 思路: kmp搞一下. #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <math.h> #include <set> using name