想到两点就行:
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