FFT
可以把题目给的式子转化为卷积的形式,然后通过FFT可以求得(推公式过程待补)

//#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> #include<complex> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define Io ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; typedef complex<double> Comp; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const double eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} namespace IO { const int len=4e7;char buf[len];int sz,p; void begin(){p=0;sz=fread(buf,1,len,stdin);} inline bool read(ll &x) { if (p==sz)return 0;int f=1,d=0;char s=buf[p++]; while(s<'0'||s>'9'&&p<sz){if(s=='-') f=-1;s=buf[p++];} while(s>='0'&&s<='9'&&p<sz){d=d*10+s-'0';s=buf[p++];} x=f*d; return p!=sz; } } inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int maxn=5e5+50; struct Complex { double x, y; Complex(double x=0,double y=0):x(x),y(y){} } a[maxn], b[maxn], c[maxn]; Complex operator + (Complex a, Complex b) { return Complex(a.x + b.x , a.y + b.y);} Complex operator - (Complex a, Complex b) { return Complex(a.x - b.x , a.y - b.y);} Complex operator * (Complex a, Complex b) { return Complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} int rev [maxn]; int lim = 1, l; void fft(Complex f[],double tag) { for (int i = 0; i < lim;++i) if(i<rev[i]) swap(f[i], f[rev[i]]); for (int mid = 1; mid <lim;mid<<=1) { Complex wn(cos(pi / mid), tag * sin(pi / mid)); for (int R = mid << 1, j = 0; j < lim;j+=R) { Complex w(1, 0); for (int k = 0; k < mid;k++,w=w*wn) { Complex x = f[j + k], y = w * f[j + mid + k]; f[j + k] = x + y; f[j + mid + k] = x - y; } } } } void run() { int n = rd(); for (int i = 1;i<=n;++i) { scanf("%lf", &a[i].x); b[i].x = 1.0 / i / i; c[n - i + 1].x = a[i].x; } while(lim<=2*n) lim <<= 1, l++; for (int i = 0; i < lim;++i) rev[i] = ((rev[i >> 1] >> 1) | ((i & 1) << (l - 1))); fft(a, 1), fft(b, 1), fft(c, 1); for (int i = 0; i <= lim;++i) a[i] = a[i] * b[i], c[i] = b[i] * c[i]; fft(a, -1), fft(c, -1); for (int i = 1; i <= n;++i) a[i].x /= lim, c[i].x /= lim; for (int i = 1;i<=n;++i) printf("%.3lf\n", a[i].x - c[n-i+1].x); } int main() { run(); return 0; } /* start time: over time: */

//#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> #include<complex> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define Io ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; typedef complex<double> Comp; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const double eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} namespace IO { const int len=4e7;char buf[len];int sz,p; void begin(){p=0;sz=fread(buf,1,len,stdin);} inline bool read(ll &x) { if (p==sz)return 0;int f=1,d=0;char s=buf[p++]; while(s<'0'||s>'9'&&p<sz){if(s=='-') f=-1;s=buf[p++];} while(s>='0'&&s<='9'&&p<sz){d=d*10+s-'0';s=buf[p++];} x=f*d; return p!=sz; } } inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int maxn=5e6+50; struct Complex { double x, y; Complex(double x=0,double y=0):x(x),y(y){} } a[maxn], b[maxn]; Complex operator + (Complex a, Complex b) { return Complex(a.x + b.x , a.y + b.y);} Complex operator - (Complex a, Complex b) { return Complex(a.x - b.x , a.y - b.y);} Complex operator * (Complex a, Complex b) { return Complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} int rev [maxn]; int lim = 1, l; void fft(Complex f[],double tag) { for (int i = 0; i < lim;++i) if(i<rev[i]) swap(f[i], f[rev[i]]); for (int mid = 1; mid <lim;mid<<=1) { Complex wn(cos(pi / mid), tag * sin(pi / mid)); for (int R = mid << 1, j = 0; j < lim;j+=R) { Complex w(1, 0); for (int k = 0; k < mid;k++,w=w*wn) { Complex x = f[j + k], y = w * f[j + mid + k]; f[j + k] = x + y; f[j + mid + k] = x - y; } } } } char s1[maxn],s2[maxn]; int ans[maxn]; void run() { scanf("%s", s1 ); scanf("%s", s2 ); int len1 = strlen(s1), len2 = strlen(s2); int tot1 = 0, tot2 = 0; for (int i = len1-1; i >= 0;--i) a[tot1++].x = s1[i] - '0'; for (int i = len2-1; i >= 0;--i) b[tot2++].x = s2[i] - '0'; while (lim <= len1 + len2) lim <<= 1, l++; for (int i = 0; i < lim; ++i) rev[i] = ((rev[i >> 1] >> 1) | ((i & 1) << (l - 1))); fft(a, 1), fft(b, 1); for (int i = 0; i <= lim; ++i) a[i] = a[i] * b[i]; fft(a, -1); for (int i = 0; i <= lim;++i) { ans[i] += int(a[i].x / lim + 0.5); if(ans[i]>=10) { ans[i + 1] = ans[i] / 10; ans[i] %= 10; lim += (i == lim); } } while(!ans[lim]&&lim>=1) lim--; lim++; while (--lim>=0) printf("%d",ans[lim]); puts(""); } int main() { run(); return 0; } /* start time: over time: */
FFT与字符串匹配

//#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> #include<complex> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define Io ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; typedef complex<double> Comp; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const double eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} namespace IO { const int len=4e7;char buf[len];int sz,p; void begin(){p=0;sz=fread(buf,1,len,stdin);} inline bool read(ll &x) { if (p==sz)return 0;int f=1,d=0;char s=buf[p++]; while(s<'0'||s>'9'&&p<sz){if(s=='-') f=-1;s=buf[p++];} while(s>='0'&&s<='9'&&p<sz){d=d*10+s-'0';s=buf[p++];} x=f*d; return p!=sz; } } inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int maxn=2e6+50; struct Complex { double x, y; Complex(double x=0,double y=0):x(x),y(y){} } a[maxn], b[maxn], c[maxn]; Complex operator + (Complex a, Complex b) { return Complex(a.x + b.x , a.y + b.y);} Complex operator - (Complex a, Complex b) { return Complex(a.x - b.x , a.y - b.y);} Complex operator * (Complex a, Complex b) { return Complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} int rev [maxn]; int lim = 1, l; void fft(Complex f[],double tag) { for (int i = 0; i < lim;++i) if(i<rev[i]) swap(f[i], f[rev[i]]); for (int mid = 1; mid <lim;mid<<=1) { Complex wn(cos(pi / mid), tag * sin(pi / mid)); for (int R = mid << 1, j = 0; j < lim;j+=R) { Complex w(1, 0); for (int k = 0; k < mid;k++,w=w*wn) { Complex x = f[j + k], y = w * f[j + mid + k]; f[j + k] = x + y; f[j + mid + k] = x - y; } } } } char s1[maxn], s2[maxn]; double f1[maxn], f2[maxn]; void run() { int n = rd(), m = rd(); scanf("%s", s1); scanf("%s", s2); for (int i = 0; i < n;++i) if(s1[i]!='*') f1[i] = s1[i] - '0'; for (int i = 0; i < m;++i) if(s2[i]!='*') f2[i] = s2[i] - '0'; reverse(f1, f1 + n); while(lim<n+m) lim <<= 1, ++l; for (int i = 0; i < lim;++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1)); for (int i = 0; i < n;++i) a[i].x = f1[i] * f1[i] * f1[i]; for (int i = 0; i < m;++i) b[i].x = f2[i]; fft(a, 1), fft(b, 1); for (int i = 0; i <= lim;++i) c[i] =c[i]+ a[i] * b[i]; for (int i = 0; i <= lim;++i) a[i] = b[i] = Complex(0, 0); for (int i = 0; i < n;++i) a[i].x = f1[i] * f1[i]; for (int i = 0; i < m;++i) b[i].x = f2[i] * f2[i]; fft(a, 1), fft(b, 1); for (int i = 0; i <= lim;++i) c[i] =c[i]-2*a[i] * b[i]; for (int i = 0; i <= lim;++i) a[i] = b[i] = Complex(0, 0); for (int i = 0; i < n;++i) a[i].x = f1[i] ; for (int i = 0; i < m;++i) b[i].x = f2[i] * f2[i] * f2[i]; fft(a, 1), fft(b, 1); for (int i = 0; i <= lim;++i) c[i] = c[i] + a[i] * b[i]; fft(c, -1); vector<int> ans; for (int i = n - 1; i <m;++i) { int cnt = int(c[i].x / lim + 0.5); if(!cnt) ans.push_back(i - n + 2); } printf("%d\n", ans.size()); //for(auto x:ans) // printf("%d ", x); for (int i = 0; i < ans.size();++i) printf("%d ", ans[i]); printf("\n"); } int main() { run(); return 0; } /* start time: over time: */

//#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> #include<complex> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define Io ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; typedef complex<double> Comp; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const double eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} namespace IO { const int len=4e7;char buf[len];int sz,p; void begin(){p=0;sz=fread(buf,1,len,stdin);} inline bool read(ll &x) { if (p==sz)return 0;int f=1,d=0;char s=buf[p++]; while(s<'0'||s>'9'&&p<sz){if(s=='-') f=-1;s=buf[p++];} while(s>='0'&&s<='9'&&p<sz){d=d*10+s-'0';s=buf[p++];} x=f*d; return p!=sz; } } inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int maxn=5e5+50; struct Complex { double x, y; Complex(double x=0,double y=0):x(x),y(y){} } a[maxn], b[maxn]; Complex operator + (Complex a, Complex b) { return Complex(a.x + b.x , a.y + b.y);} Complex operator - (Complex a, Complex b) { return Complex(a.x - b.x , a.y - b.y);} Complex operator * (Complex a, Complex b) { return Complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} int rev [maxn]; int lim = 1, l; void fft(Complex f[],double tag) { for (int i = 0; i < lim;++i) if(i<rev[i]) swap(f[i], f[rev[i]]); for (int mid = 1; mid <lim;mid<<=1) { Complex wn(cos(pi / mid), tag * sin(pi / mid)); for (int R = mid << 1, j = 0; j < lim;j+=R) { Complex w(1, 0); for (int k = 0; k < mid;k++,w=w*wn) { Complex x = f[j + k], y = w * f[j + mid + k]; f[j + k] = x + y; f[j + mid + k] = x - y; } } } } char C[4] = {'A', 'T', 'C', 'G'}; char s1[maxn],s2[maxn]; int ans[maxn]; void run() { int _ = rd(); while(_--) { scanf("%s", s1); scanf("%s", s2); memset(ans, 0, sizeof ans); int len1 = strlen(s1), len2 = strlen(s2); while (lim < len1 +len2) lim <<= 1, l++; for (int i = 0; i < lim;++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1)); for (int i = 0; i < 4; ++i) { for (int j = 0; j < len1;++j) a[j].x = (s1[j] == C[i]); for (int j = 0; j < len2;++j) b[j].x = (s2[j] == C[i]); reverse(b, b + len2); fft(a, 1), fft(b, 1); for (int j = 0; j <= lim;++j) a[j] = a[j] * b[j]; fft(a, -1); for (int j = len2 - 1; j < len1;++j) ans[j] += (int(a[j].x / lim + 0.5)); for (int j = 0; j <= lim;++j) a[j] = b[j] = Complex(0, 0); //for (int j = 0; j < len2;) } int num = 0; for (int i = len2 - 1; i < len1;++i) { if(ans[i]+3>=len2) num++; } printf("%d\n", num); } } int main() { run(); return 0; } /* start time: over time: */
例题五: Forgiving Matching

//#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> #include<complex> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define Io ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; typedef complex<double> Comp; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const double eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} namespace IO { const int len=4e7;char buf[len];int sz,p; void begin(){p=0;sz=fread(buf,1,len,stdin);} inline bool read(ll &x) { if (p==sz)return 0;int f=1,d=0;char s=buf[p++]; while(s<'0'||s>'9'&&p<sz){if(s=='-') f=-1;s=buf[p++];} while(s>='0'&&s<='9'&&p<sz){d=d*10+s-'0';s=buf[p++];} x=f*d; return p!=sz; } } inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int maxn=2e6+50; struct Complex { double x, y; Complex(double x=0,double y=0):x(x),y(y){} } a[maxn], b[maxn]; Complex operator + (Complex a, Complex b) { return Complex(a.x + b.x , a.y + b.y);} Complex operator - (Complex a, Complex b) { return Complex(a.x - b.x , a.y - b.y);} Complex operator * (Complex a, Complex b) { return Complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} int rev [maxn]; int lim = 1, l; void fft(Complex f[],double tag) { for (int i = 0; i < lim;++i) if(i<rev[i]) swap(f[i], f[rev[i]]); for (int mid = 1; mid <lim;mid<<=1) { Complex wn(cos(pi / mid), tag * sin(pi / mid)); for (int R = mid << 1, j = 0; j < lim;j+=R) { Complex w(1, 0); for (int k = 0; k < mid;k++,w=w*wn) { Complex x = f[j + k], y = w * f[j + mid + k]; f[j + k] = x + y; f[j + mid + k] = x - y; } } } } char s1[maxn], s2[maxn]; ll ans[maxn], num[maxn],sum1[maxn],sum2[maxn]; void work1(char s[],int len,ll sum[]) { sum[0] = (s[0] == '*'); for (int i = 1; i < len;++i) sum[i] = sum[i - 1] + (s[i] == '*'); } void run() { int _; scanf("%d", &_); while(_--) { int n, m; scanf("%d%d", &n, &m); scanf("%s", s1); scanf("%s", s2); memset(ans, 0, sizeof ans); memset(num, 0, sizeof num); memset(sum1, 0, sizeof sum1); memset(sum2, 0, sizeof sum2); reverse(s2, s2 + m); work1(s1, n, sum1); work1(s2, m, sum2); //rep(i, 0, n - 1) cout << sum1[i] << " "; //cout << endl; lim = 1, l = 0; while(lim<n+m) lim <<= 1, l++; for (int i = 0; i < lim;++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1)); /*for (char c = '0'; c <= '9';++c) { for (int i = 0;i<n;++i) if(s1[i]==c||s1[i]=='*') a[i].x = 1; for (int i = 0; i < m;++i) if(s2[i]==c) b[i].x = 1; fft(a,1),fft(b,1); for (int i = 0; i < lim;++i) a[i] = a[i] * b[i]; fft(a, -1); for (int i = m - 1; i < n;++i) num[i] += ll(a[i].x / lim + 0.5); for (int i = 0; i < lim;++i) a[i] = b[i] = Complex(0, 0); } for (int i = 0;i<n;++i) a[i].x = 1; for (int i = 0; i < m;++i) if(s2[i]=='*') b[i].x = 1; fft(a,1),fft(b,1); for (int i = 0; i < lim;++i) a[i] = a[i] * b[i]; fft(a, -1); for (int i = m - 1; i < n;++i) num[i] += ll(a[i].x / lim + 0.5); for (int i = 0; i < lim;++i) a[i] = b[i] = Complex(0, 0); for (int i = m - 1;i<n;++i) ans[m - num[i]]++; for (int i = 1; i <= m;++i) ans[i] += ans[i - 1]; for (int i = 0;i<=m;++i) printf("%d\n", ans[i]); //cout << ans[i] << "\n"; */ for (int i = 0; i <= 10;++i) { char tar; if(i<10) tar = char('0' + i); if(i==10) tar = '*'; for (int j = 0; j < n;++j) a[j].x = (s1[j] == tar); for (int j = 0; j < m;++j) b[j].x = (s2[j] == tar); fft(a, 1), fft(b, 1); for (int j = 0; j < lim;++j) a[j] = a[j] * b[j]; fft(a, -1); for (int j = m - 1; j < n;++j) { if(i<10) num[j] += ll(a[j].x / lim + 0.5); else num[j] -= ll(a[j].x / lim + 0.5); } for (int j = 0; j < lim;++j) a[j] =b[j]= Complex(0, 0); } for (int i = m - 1; i < n;++i) { //cout << i << " " << num[i] << endl; if(i==m-1) num[i] += sum1[i] + sum2[m-1]; else num[i] += sum1[i] + sum2[m-1] - sum1[i - m]; //cout << i << " " << num[i] << endl; ans[m - num[i]]++; } for (int i = 1; i <=m;++i) ans[i] += ans[i - 1]; for (int i = 0;i<=m;++i) printf("%d\n", ans[i]); } } int main() { run(); return 0; } /* start time: over time: */
分治FFT