CCPC[长春] 8.Sequence I KMP and similar

Sequence I

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
Mr. Frog has two sequences  a1,a2,,an  and  b1,b2,,bm  and a number p. He wants to know the number of positions q such that sequence  b1,b2,,bm  is exactly the sequence  aq,aq+p,aq+2p,,aq+(m1)p  where  q+(m1)pn  and  q1 .
 

Input
The first line contains only one integer  T100 , which indicates the number of test cases.

Each test case contains three lines.

The first line contains three space-separated integers  1n106,1m106  and  1p106 .

The second line contains n integers  a1,a2,,an(1ai109) .

the third line contains m integers  b1,b2,,bm(1bi109) .
 

Output
For each test case, output one line “Case #x: y”, where x is the case number (starting from 1) and y is the number of valid q’s.
 

Sample Input
   
   
2 6 3 1 1 2 3 1 2 3 1 2 3 6 3 2 1 3 2 2 3 1 1 2 3
 

Sample Output
   
   
Case #1: 2 Case #2: 1
 

Statistic |  Submit |  Clarifications |  Back



KMP匹配,就是把一个串分成p个串去匹配



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
const int inf_int = 2e9;
const long long inf_ll = 2e18;
#define inf_add 0x3f3f3f3f
#define mod 1000000007
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define PI acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=5e2+10;
using namespace std;
typedef  long long ll;
typedef  unsigned long long  ull; 
inline int read(){int ra,fh;char rx;rx=getchar(),ra=0,fh=1;
while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')
fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,
rx=getchar();return ra*fh;}
//#pragma comment(linker, "/STACK:102400000,102400000")
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};


int inext[1000005];
ll p;
ll a[1000005];
ll b[1000005];

ll KMP_Count(ll x[],ll m,ll y[],ll n);
//void preKMP(ll x[],ll m,ll kmpNext[]);
void kmp_pre(ll x[],ll m);


int main()
{
    int T;
    ll n,m;
    scanf("%d",&T);
    for(int k=1;k<=T;k++)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(inext,0,sizeof(inext));
        scanf("%lld %lld %lld",&n,&m,&p);
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        for(int i=0;i<m;i++)
            scanf("%lld",&b[i]);
            
        ll re = KMP_Count(b,m,a,n);
        printf("Case #%d: %lld\n",k,re);
    } 
    return 0;
}


void kmp_pre(ll x[],ll m)
{
    ll i,j;
    j=inext[0]=-1;
    i=0;
    while(i<m)
    {
        while(-1 != j&& x[i] != x[j])  
            j=inext[j];
        inext[++i]=++j;
    }
}



ll KMP_Count(ll x[],ll m,ll y[],ll n)
{
    ll i,j,ci=0;
    ll ans = 0;
    kmp_pre(x,m);
    
    
    for(int k=0;k<p;k++)//分成p个串
    {
        i=k;
        j=0;
        while(i<n)
        {
        
            while(-1!=j && y[i]!=x[j])  
                j=inext[j];
        
            i+=p;
            j++;
            if(j>=m)
            {
                
                ans++;
                j=inext[j];
            }
        }
    }
    
    return ans;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值