博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bzoj4259: 残缺的字符串
阅读量:6831 次
发布时间:2019-06-26

本文共 3480 字,大约阅读时间需要 11 分钟。

题面

Sol

假设没有通配符

那么把\(T\)翻转
\(f[i]=\sum_{j+k=i}[S[k]==T[j]]\)
如果\(f[i]\)\(0\)\(i\)之前的一一匹配
那么可以给每个字符一个权值
重新定义\(f[i]=\sum_{j+k=i}(S[k]-T[j])^2\)
就可以\(FFT\)

然后有通配符,设权值为\(0\)

再定义
\(f[i]=\sum_{j+k=i}(S[k]-T[j])^2S[k]T[j]\)

然后拆开\(FFT\)就可以了

# include 
# define IL inline# define RG register# define Fill(a, b) memset(a, b, sizeof(a))using namespace std;typedef long long ll;template
IL void Input(RG Int &x){ RG int z = 1; RG char c = getchar(); x = 0; for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); x *= z;}const int maxn(3e5 + 5);const int oo(1e9);const double pi(acos(-1));int n, m, k, r[maxn << 2], len, cnt, v1[maxn], v2[maxn], ans[maxn];char s[maxn], t[maxn];struct Complex{ double real, image; IL Complex(){ real = image = 0; } IL Complex(RG double a, RG double b){ real = a, image = b; } IL Complex operator +(RG Complex b){ return Complex(real + b.real, image + b.image); } IL Complex operator -(RG Complex b){ return Complex(real - b.real, image - b.image); } IL Complex operator *(RG Complex b){ return Complex(real * b.real - image * b.image, real * b.image + image * b.real); } IL Complex operator *(RG int b){ return Complex(real * b, image * b); }} a[maxn << 2], b[maxn << 2], w[maxn << 2], c[maxn << 2];IL void FFT(RG Complex *p, RG int opt){ for(RG int i = 0; i < len; ++i) if(r[i] < i) swap(p[i], p[r[i]]); for(RG int i = 1; i < len; i <<= 1) for(RG int j = 0, l = i << 1; j < len; j += l){ for(RG int k = 0; k < i; ++k){ RG Complex wn = Complex(w[len / i * k].real, w[len / i * k].image * opt); RG Complex x = p[k + j], y = wn * p[k + j + i]; p[k + j] = x + y, p[k + j + i] = x - y; } }}IL void Prepare(){ RG int l = 0, tmp = m + n - 1; for(len = 1; len < tmp; len <<= 1) ++l; for(RG int i = 0; i < len; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1)); for(RG int i = 1; i <= len; i <<= 1) for(RG int k = 0; k < i; ++k) w[len / i * k] = Complex(cos(pi / i * k), sin(pi / i * k));}int main(RG int argc, RG char* argv[]){ Input(m), Input(n), scanf(" %s %s", t, s); reverse(t, t + m), Prepare(); for(RG int i = 0; i < n; ++i) v1[i] = s[i] == '*' ? 0 : s[i] - 'a' + 1; for(RG int i = 0; i < m; ++i) v2[i] = t[i] == '*' ? 0 : t[i] - 'a' + 1; for(RG int i = 0; i < n; ++i) a[i].real = v1[i] * v1[i] * v1[i]; for(RG int i = 0; i < m; ++i) b[i].real = v2[i]; FFT(a, 1), FFT(b, 1); for(RG int i = 0; i < len; ++i) c[i] = c[i] + a[i] * b[i], a[i] = b[i] = Complex(0, 0); for(RG int i = 0; i < n; ++i) a[i].real = v1[i] * v1[i] << 1; for(RG int i = 0; i < m; ++i) b[i].real = v2[i] * v2[i]; FFT(a, 1), FFT(b, 1); for(RG int i = 0; i < len; ++i) c[i] = c[i] - a[i] * b[i], a[i] = b[i] = Complex(0, 0); for(RG int i = 0; i < n; ++i) a[i].real = v1[i]; for(RG int i = 0; i < m; ++i) b[i].real = v2[i] * v2[i] * v2[i]; FFT(a, 1), FFT(b, 1); for(RG int i = 0; i < len; ++i) c[i] = c[i] + a[i] * b[i]; FFT(c, -1); for(RG int i = m - 1; i < n; ++i) if(!(int(c[i].real / len + 0.5))) ans[++cnt] = i; printf("%d\n", cnt); for(RG int i = 1; i <= cnt; ++i) printf("%d ", ans[i] - m + 2); return puts(""), 0;}

转载于:https://www.cnblogs.com/cjoieryl/p/8820748.html

你可能感兴趣的文章
(转)S5PV210--1---210启动方式和代码前16字节
查看>>
Zlib与GZip - woaidongmao - C++博客
查看>>
ASP.NET那点不为人知的事(四)
查看>>
ExtJs 4.2 treePanel
查看>>
typeof和instanceof的区别
查看>>
Windows 7下面安装VMware、BackTrack5(BT5)、minidwep-gtk
查看>>
Java中获取键盘输入值的三种方法
查看>>
最少硬币问题(受限)NK1132
查看>>
ltrace查看库调用
查看>>
spring3.0事务配置及expression表达式介绍
查看>>
head设计模式 01
查看>>
PostgreSQL的神秘现象
查看>>
windows下安装redis
查看>>
使用doxygen生成中文pdf文档
查看>>
安全卫士分析--号码归属地
查看>>
常用计数器的verilog实现(binary、gray、one-hot、LFSR、环形、扭环形)
查看>>
CCS学习资料汇总
查看>>
WCF 中 TCP 与 HTTP 性能简单比较
查看>>
04 企业的结构
查看>>
FlipViewDemo
查看>>