CF471D MUH and Cube Walls

题意

传送门

给两堵墙。问a墙中与b墙顶部形状相同的区间有多少个

分析

KMP+差分

根据样例解释,我们很容易就能发现:

这里所求的形状,实质上其实就是相邻两个墙的高度的差来确定的

只要差相等,那么形状不就相等了

所以我们考虑将原数组差分,然后这里问的是相等的区间,就是将两个差分数组进行匹配

那么直接KMP,匹配到了多少个答案就是多少,套板子即可

代码

#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
    x=0;char ch=getchar();bool f=false;
    while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return ;
}
template <typename T,typename... Args> inline void read(T& t, Args&... args){read(t);read(args...);}
template <typename T>
inline void write(T x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10^48);
    return ;
}
template <typename T>
inline void print(T x){write(x),putchar(' ');}
#define ll long long
#define ull unsigned long long
#define inc(x,y) (x+y>=MOD?x+y-MOD:x+y)
#define dec(x,y) (x-y<0?x-y+MOD:x-y)
#define min(x,y) (x<y?x:y)
#define max(x,y) (x>y?x:y)
const int N=2e5+5,M=1e6+5,MOD=1e9+7;
int n,m,a[N],b[N],kmp[N<<1],ans;
int main(){
    read(n),read(m);
	if(m==1){write(n);return 0;}//注意特判
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=1;i<n;i++) a[i]-=a[i+1];
	for(int i=1;i<=m;i++) read(b[i]);
	for(int i=1;i<m;i++) b[i]-=b[i+1];
	b[m]=-100009,n--;//相当于隔离的作用
	for(int i=m+1;i<=m+n;i++) b[i]=a[i-m];//拼接两个字符串
	for(int i=2,j=0;i<=n+m;i++){
		while(j&&b[j+1]!=b[i]) j=kmp[j];
		if(b[j+1]==b[i]) j++;
		kmp[i]=j;
		if(j==m-1) ans++;
	}
	write(ans);
    return 0;
}

posted @ 2020-12-28 10:10  __Anchor  阅读(65)  评论(0编辑  收藏  举报