|
| 1 | +#include<bits/stdc++.h> |
| 2 | +using namespace std; |
| 3 | +using cd = complex<double>; |
| 4 | +#define pb push_back |
| 5 | +#define nfs_mw ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); |
| 6 | +double PI = acos(-1); |
| 7 | +int next_pow2(int no) { for(int i=0;i<6;i++) no |= no>>(1<<i); return (no+1); } |
| 8 | + |
| 9 | +void fft(vector<cd>& pol, int inv = 1) |
| 10 | +{ |
| 11 | + int n = pol.size(),i,j,l,jump,ang; |
| 12 | + if(n==1) return; |
| 13 | + |
| 14 | + cd w[n]={cd(1.0,0.0)}, w1 = cd(cos((2*PI*inv)/n),sin((2*PI*inv)/n)); |
| 15 | + for(i=1; i<n; i++) w[i] = w[i-1]*w1; |
| 16 | + |
| 17 | + for (i=1, j=0; i<n; i++) { |
| 18 | + int bit = n >> 1; |
| 19 | + for (; j&bit; bit>>=1) |
| 20 | + j ^= bit; |
| 21 | + j ^= bit; |
| 22 | + |
| 23 | + if (i < j) |
| 24 | + swap(pol[i], pol[j]); |
| 25 | + } |
| 26 | + |
| 27 | + for(l=2; l<=n; l = l<<1)//length of merged block |
| 28 | + for(i=0; i<n; i += l)//iterate over the blocks |
| 29 | + for(j=0,ang=0,jump=n/l; j<l/2; j++,ang += jump)//form each block |
| 30 | + { |
| 31 | + cd& u = pol[i+j]; cd& v = pol[i+j+l/2]; cd mul = w[ang]; |
| 32 | + tie(u,v) = make_tuple(u + mul*v, u - mul*v); |
| 33 | + } |
| 34 | + |
| 35 | + return; |
| 36 | +} |
| 37 | + |
| 38 | +void print(vector<cd> poly) |
| 39 | +{ |
| 40 | + for(int i=0; i<poly.size(); i++) cout<<((int)round(poly[i].real()))<<" "; cout<<"\n"; |
| 41 | +} |
| 42 | + |
| 43 | +vector<cd> polymul(vector<cd> a, vector<cd> b) |
| 44 | +{ |
| 45 | + int n = next_pow2( a.size() + b.size() - 1 ),i; |
| 46 | + a.resize(n,cd(0.0, 0.0)); b.resize(n,cd(0.0, 0.0)); |
| 47 | + fft(a); |
| 48 | + fft(b); |
| 49 | + |
| 50 | + vector <cd> fab; |
| 51 | + transform(a.begin(), a.end(), b.begin(), back_inserter(fab), multiplies<cd>()); |
| 52 | + |
| 53 | + fft(fab,-1); |
| 54 | + for(i=0; i<n; i++) fab[i] /= n; |
| 55 | + return fab; |
| 56 | +} |
| 57 | + |
| 58 | +int main() |
| 59 | +{ |
| 60 | + // nfs_mw |
| 61 | + int i,j,maxm = 0,l,c,lr; |
| 62 | + string s,r; |
| 63 | + cin>>s>>r; l=s.length(); lr=r.length(); |
| 64 | + int ref[100]={}; ref['A'] = 0; ref['G'] = 1; ref['C'] = 2; ref['T'] = 3; |
| 65 | + vector <cd> pol[4][3]; |
| 66 | + for(i=0; i<4; i++) { pol[i][0].resize(l,cd(0.0,0.0)); pol[i][1].resize(lr,cd(0.0,0.0)); } |
| 67 | + for(i=0; i<l; i++) { |
| 68 | + c = ref[(int)s[i]]; |
| 69 | + pol[c][0][i] = cd(1.0,0.0); |
| 70 | + } |
| 71 | + for(i=0;i<lr;i++){ |
| 72 | + c = ref[r[i]]; |
| 73 | + pol[c][1][lr-1-i] = cd(1.0,0.0); |
| 74 | + } |
| 75 | + |
| 76 | + for(i=0;i<4;i++){ |
| 77 | + pol[i][2] = polymul(pol[i][0],pol[i][1]); |
| 78 | + } |
| 79 | + |
| 80 | + for(i=0; i<=l-lr; i++){ |
| 81 | + int tmp=0; |
| 82 | + for(j=0;j<4;j++) tmp += (pol[j][2].size()>(i+lr-1))?(round(pol[j][2][i+lr-1].real())):0; |
| 83 | + maxm = max(tmp,maxm); |
| 84 | + } |
| 85 | + cout<<(lr-maxm)<<"\n"; |
| 86 | +} |
0 commit comments