标签:eve sign print des hdu esc signed length define
题意:
给定两个串,求其中一个串 s
的每个后缀在另一个串 t
中出现的次数
题解:
把两个串都 reverse 一下,给 t
做个 KMP 之后让 s
在 KMP 出来的结果上跑一边就好了。
比赛水过去了
baabaa
caabaa
应该输出23
重新写过后,KMP还是可以过的
#include<bits/stdc++.h> using namespace std; #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; typedef unsigned long long ULL; const long long INF = 1e18+1LL; const double pi = acos(-1.0); const int N=1e6+20,M=1e6+10,inf=2147483647,mod = 1e9+7; int T,fail[N],sum[N]; char s[N],t[N],a[N],b[N]; int main() { scanf("%d",&T); while(T--) { scanf("%s%s",a,b); for(int i = 0; i < N; ++i) fail[i] = -1,sum[i] = 0; int m = strlen(b); int n = strlen(a); for(int i = 0; i < n; ++i) s[n-i-1] = a[i]; for(int i = 0; i < m; ++i) t[m-i-1] = b[i]; int j = -1; sum[0] = 1; for(int i = 1; i < m; ++i) { while(j!=-1&&t[j+1]!=t[i]) j = fail[j]; if(t[j+1] == t[i]) j++; fail[i] = j; if(j!=-1)sum[i] = (sum[j] + i+1) % mod; else sum[i] = i+1; } LL ans = 0; j = -1; for(int i = 0; i < n; ++i) { int tmp = j; if(j!=-1) ans = (ans + sum[j]) % mod; while(j!=-1&&t[j+1]!=s[i]) { j = fail[j]; } if(t[j+1] == s[i] && j+1<m) j++; if(j == m-1) ans = (ans + j+1) % mod, j = fail[j]; } if(j!=-1) ans = (ans + sum[j]) % mod; printf("%lld\n",ans); } return 0; } /* 2 baabaa caabaa */
标签:eve sign print des hdu esc signed length define
原文地址:http://www.cnblogs.com/zxhl/p/7404490.html