Test instructions: Definition of Hamming distance: two different characters in a string of the same length. Now we give the number of strings A and the pattern string B, to find out how many different substrings in A and b Hamming distance <=k
Analysis: The character A is treated as a 1,b 0. Then A and B are all A's position product is 1. B is now reversed, and the length of B is n, so \ (C (n+k-1) = \sum_{i=0}^{n-1}a_{i+k}*b_{n-i-1}\), Indicates that the number of substrings in the string a from the position k, the length n, and the characters in B are all ' a ', can be obtained by FFT. The same operation is done for the character ' B ', and\ (ans[i]\) counts the number of substrings in the string A that end with I in the same character as B.
Set a the length of M, then there are \ (m-n+1\) substrings, if \ (N-ans[i] \leq k\), then the lid string matches the conditions, but the subject needs to find different substrings, so the mother string hash out, will meet the requirements of the hash value exists in the set of the weight.
#include <bits/stdc++.h>using namespace Std;typedef long long ll;const int MAXN = 4e5 + 10;const Double PI = ACOs (-1 .0); struct complex{double x, y; Inline Complex operator+ (const Complex B) Const {return (Complex) {x +b.x,y + b.y}; } inline Complex operator-(const Complex B) Const {return (Complex) {X-B.X,Y-B.Y}; } inline Complex operator* (const Complex B) Const {return (Complex) {x *b.x-y * b.y,x * b.y + y * b.x}; }} VA[MAXN * 2 + MAXN/2], VB[MAXN * 2 + maxn/2];int lenth = 1, REV[MAXN * 2 + maxn/2];int N, M; Number of F and g//f g and coefficient/convolution result//large number product int f[maxn],g[maxn];vector<ll> conv;vector<ll> multi;//f gvoid Init () {int Tim = 0; Lenth = 1; Conv.clear (), multi.clear (); memset (VA, 0, sizeof VA); Memset (VB, 0, sizeof VB); while (lenth <= N + M-2) lenth <<= 1, tim++; for (int i = 0; i < lenth; i++) rev[i] = (rev[i >> 1] >> 1) + ((I & 1) << (tim-1));} void FFT (Complex *a, CONST int fla) {for (int i = 0; i < lenth; i++) {if (I < rev[i]) {Swap (a[i ], A[rev[i]]); }} for (int i = 1; i < lenth; I <<= 1) {const Complex w = (Complex) {cos (PI/I), Fla * sin (pi/i)} ; for (int j = 0; J < lenth; J + = (I << 1)) {Complex K = (Complex) {1, 0}; for (int k = 0; k < i; k++, k = k * W) {const Complex x = A[j + K], y = k * a[j + k + i]; A[j + K] = x + y; A[j + k + i] = x-y; }}}}void Getconv () {//Find polynomial init (); for (int i = 0; i < N; i++) va[i].x = F[i]; for (int i = 0; i < M; i++) vb[i].x = G[i]; FFT (VA, 1), FFT (VB, 1); for (int i = 0; i < lenth; i++) va[i] = va[i] * Vb[i]; FFT (VA,-1); for (int i = 0; I <= N + M-2; i++) Conv.push_back ((LL) (Va[i].x/lenth + 0.5));} Char s1[100005],s2[100005]; LL Res[maxn];const int seed = 3; LL dig[maxn],hash[maxn];set<ll> dp;void Pre () {dig[0] = 1; for (int i=1;i<=100005;++i) {Dig[i] = dig[i-1]*seed; }}ll gethash (int L, int R) {if (l==0) return hash[r]; return Hash[r]-hash[l-1]*dig[r-l+1];} int main () {#ifndef Online_judge freopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); #endif pre (); int K,cas=1; while (scanf ("%d", &k) ==1) {if (k==-1) break; memset (res,0,sizeof (res)); Dp.clear (); scanf ("%s", S1); scanf ("%s", S2); int len1 = strlen (S1), len2 = strlen (s2); N = len1, M = len2; for (int i=0;i<len1;++i) {if (s1[i]== ' a ') f[i] = 1; else f[i] = 0; } for (int i=0;i<len2;++i) {if (s2[len2-i-1]== ' a ') g[i] = 1; else g[i] = 0; } getconv (); int sz =conv.size (); for (int i=len2-1;i<sz;++i) {Res[i] + = Conv[i]; } for (int i=0;i<Len1;++i) {if (s1[i]== ' B ') f[i] = 1; else f[i] = 0; } for (int i=0;i<len2;++i) {if (s2[len2-i-1]== ' B ') g[i] = 1; else g[i] = 0; } getconv (); SZ =conv.size (); for (int i=len2-1;i<sz;++i) {Res[i] + = Conv[i]; }//hash hash[0] = s1[0]-' a ' +1; for (int i=1;i<len1;++i) {Hash[i] = hash[i-1]*seed + s1[i]-' a ' +1; } for (int i=len2-1;i<len1;++i) {LL now = Gethash (i-len2+1,i); if (len2-res[i]<=k) {Dp.insert (now); }} printf ("Case%d:%d\n", cas++, (int) dp.size ()); } return 0;}
UVALive-4671 K-neighbor substrings (fft+ hash)