【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>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const double pi = acos(-1.0);
const int INF = 100000000;
const int MAXN = 2*1e5+50;
const ull B = 1e8+7;

//ll a[MAXN],b[MAXN];
//const int MAXN = 1000+10;
ll T[MAXN],P[MAXN];//T--文本,P--模板串
int fail[MAXN];
int n,w;
void getfail()
{
    int m=w;
    fail[0]=fail[1]=0;
    for(int i=1;i<m;i++)
    {
        int j=fail[i];
        while(j && P[i]!=P[j])j=fail[j];
        fail[i+1]=P[i]==P[j]?j+1:0;
    }
}

int Find()
{
    //int n=strlen(T),m=strlen(P);
    int m=w,ret=0;
    if(w>n)return 0;
    getfail();
    int j=0;
    for(int i=0;i<=n;i++)/// i<n WA??为什么??
    {
        while(j && P[j]!=T[i])j=fail[j];
        if(P[j] == T[i])j++;
        if(j==m)//printf("%d\n",i-m+1);//find it
        {
            //j = fail[j];///////
            ret++;
        }
    }
    return ret;
}

int main()
{
    //IN("D.txt");
    //init();
    while(~scanf("%d%d",&n,&w))
    {
       for(int i=0;i<n;i++)
            scanf("%I64d",&T[i]);
        for(int i=0;i<w;i++)
            scanf("%I64d",&P[i]);
       for(int i=0;i<n-1;i++)
            T[i]=T[i+1]-T[i]+2*1e9;//,printf("%I64d ",T[i]);
       for(int i=0;i<w-1;i++)
            P[i]=P[i+1]-P[i]+2*1e9;
        if(w==1)P[0]=2*1e9;
        w--,n--;
        printf("%d\n",Find());
    }
    return 0;
}

HASH

//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const double pi = acos(-1.0);
const int INF = 100000000;
const int MAXN = 2*1e5+50;
const ull B = 1e8+7;

ll a[MAXN],b[MAXN], aa[MAXN],bb[MAXN];
ull base[MAXN];
//ha[MAXN],hb[MAXN],
int n,w;

void init()
{
    base[0]=1;
    for(int i=1;i<MAXN;i++)
        base[i]=base[i-1]*B;
}

int solve()
{
    int ret=0;
    if(w>n)return 0;
    ull ha=0,hb=0,t=1;
    for(int i=1;i<w;i++)
        hb=hb*B+b[i],ha=ha*B+a[i],t*=B;

    for(int i=1;i+w-1<=n;i++)
    {
        if(ha == hb )ret++;//,cout << i << endl;
        ha=ha*B + a[i+w-1] -a[i]*t;
    }

    return ret;
}

int main()
{
    //IN("D.txt");
    //init();
    while(~scanf("%d%d",&n,&w))
    {
       for(int i=0;i<n;i++)
            scanf("%I64d",&aa[i]);
        for(int i=0;i<w;i++)
            scanf("%I64d",&bb[i]);
       for(int i=n-1;i>=1;i--)
            a[i]=aa[i]-aa[i-1];//+2*1e9;
       for(int i=w-1;i>=1;i--)
            b[i]=bb[i]-bb[i-1];//+2*1e9;
        printf("%d\n",solve());
    }
    return 0;
}
时间: 2024-10-21 09:06:58

【CodeForces】471D MUH and Cube Walls KMP或者字符串HASH的相关文章

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 Round #269 (Div. 2) D. MUH and Cube Walls KMP

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. T

D - MUH and Cube Walls

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. T

poj 3461 字符串单串匹配--KMP或者字符串HASH

http://poj.org/problem?id=3461 先来一发KMP算法: #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <cmath> #include <map> #include <queue> using namespace std;

codeforces MUH and Cube Walls

题意:给定两个序列a ,b, 如果在a中存在一段连续的序列使得 a[i]-b[0]==k, a[i+1]-b[1]==k.... a[i+n-1]-b[n-1]==k 就说b串在a串中出现过!最后输出b串在a串中出现几次! 思路: KMP变形!如何转换成KMP求解呢? 举一个例子说明一下: a: 5 10 8 10 11 9 11 12 10 15 b: 4 2 4 5 3 根据题意 a中的 10 8 10 11 9 与 b是匹配的, 11 9 11 12 10跟b也是匹配的! 如何将b串以及

#269(div2) D. MUH and Cube Walls

题意:2个序列A,B,B可以自身全部加减某个数字,问B和A匹配的个数 思路:不管怎样,B序列中相邻2个数之间的差是不变的,然后KMP. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=200005; 4 5 int aa[N],a[N]; 6 int bb[N],b[N]; 7 int n,m; 8 int Next[N]; 9 10 void getnext() 11 { 12 int j, k; 13 j = 0

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 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 nex

codeforces 525 D Arthur and Walls

题意: 给出一个n*m的表格,里面有'*'和'.',求把最少的'*'移除掉,使得'.'所在的连通块是矩形. 限制: 1 <= n,m <= 2000 思路: 2*2地考虑,如果2*2的格子里只有一个'*',说明这个'*'要去掉,其他情况都不用去掉.然后去掉这个'*'后,又会对其他四个格子有影响. 复杂度好难估计. /*codeforces 525 D Arthur and Walls 题意: 给出一个n*m的表格,里面有'*'和'.',求把最少的'*'移除掉,使得'.'所在的连通块是矩形. 限