栗酱的数列

题目链接
题意:t组数据,每组n,m,k,长度为n的数组a,长度为m的数组b,询问a中有多少长度为m的子串a1满足 ( a 1 + b 1 ) % k = . . . = ( a i + b i ) % k = . . . = ( a m + b m ) % k (a_1+b_1)\%k=...=(a_i+b_i)\%k=...=(a_{m}+b_{m})\%k (a1+b1)%k=...=(ai+bi)%k=...=(am+bm)%k

2 < = n , m < = 2 e 5 2<=n,m<=2e5 2<=n,m<=2e5
1 < = a i , b i , k < = 1 e 9 1<=a_i,b_i,k<=1e9 1<=ai,bi,k<=1e9

对于 ( a i + b i ) % k = ( a i + 1 + b i + 1 ) % k (a_i+b_i)\%k=(a_{i+1}+b_{i+1})\%k (ai+bi)%k=(ai+1+bi+1)%k,我们可以将其化为 ( a i − a i + 1 ) % k = ( b i + 1 − b i ) % k (a_i-a_{i+1})\%k=(b_{i+1}-b_i)\%k (aiai+1)%k=(bi+1bi)%k,将a,b数组这样处理后,等价于在a询问有多少长度为m-1的子串a1满足 a 1 = b 1 , a 2 = b 2 , . . . , a m = b m a_1=b_1,a_2=b_2,...,a_m=b_m a1=b1,a2=b2...,am=bm,等价于KMP的裸题。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int nex[maxn];
int a[maxn],b[maxn];
void get_next(int a[],int n)
{
    int k=-1;nex[0]=-1;
    for(int i=1;i<n;i++)
    {
        while(k>=0&&a[k+1]!=a[i])
        k=nex[k];
        if(a[k+1]==a[i]) k++;
        nex[i]=k;
    }
}
int ans=0;
void kmp(int a[],int n,int b[],int m)
{
    int k=-1;
    get_next(b,m);
    for(int i=0;i<n;i++)
    {
        while(k>=0&&b[k+1]!=a[i])
        k=nex[k];
        if(b[k+1]==a[i]) k++;
        if(k==m-1)
        {
            ans++;
            k=nex[k];
        }
    }
}
int main() 
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;cin>>t;
    while(t--)
    {
        int n,m,k;cin>>n>>m>>k;
        for(int i=0;i<n;i++)
        cin>>a[i],a[i]%=k;
        for(int i=0;i<m;i++)
        cin>>b[i],b[i]%=k;
        n--;m--;
        for(int i=0;i<n;i++)             //[0,n-1]
        a[i]=((a[i+1]-a[i])%k+k)%k;
        for(int i=0;i<m;i++)
        b[i]=((b[i]-b[1+i])%k+k)%k;        

        ans=0;kmp(a,n,b,m);
        cout<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值