【BZOJ4259】 残缺的字符串
Description
Input
Output
Sample Input
a*b
aebr*ob
Sample Output
1 5
HINT
Source
Solution
对于每个字母的权值就设为1~26。*的权值设为0。两个字符可以匹配当且仅当A_i∗B_j∗(A_i−B_j )^2等于0。那么我们将这个式子展开,展开以后的每一项分别用FFT计算即可。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring> #define R register
#define maxn 1048576
typedef long double db;
const db pi = acosl(-);
char A[maxn], B[maxn];
struct Complex {
db x, y;
inline Complex operator - (const Complex &that) const {return (Complex) {x - that.x, y - that.y};}
inline Complex operator * (const Complex &that) const {return (Complex) {x * that.x - y * that.y, x * that.y + y * that.x};}
inline void operator += (const Complex &that) {x += that.x; y += that.y;}
} w[maxn];
int N;
void init()
{
R int h = N >> ;
for (R int i = ; i < h; ++i) w[i + h] = (Complex) {cos( * pi / N * i), sin( * pi / N * i)};
for (R int i = h; i--; ) w[i] = w[i << ];
}
void bit_reverse(R Complex *a, R Complex *b)
{
for (R int i = ; i < N; ++i) b[i] = a[i];
for (R int i = , j = ; i < N; ++i)
{
i > j ? std::swap(b[i], b[j]), : ;
for (R int l = N >> ; (j ^= l) < l; l >>= );
}
}
void dft(R Complex *a)
{
for (R int l = , m = ; m != N; l <<= , m <<= )
for (R int i = ; i < N; i += l)
for (R int j = ; j < m; ++j)
{
R Complex tmp = a[i + j + m] * w[j + m];
a[i + j + m] = a[i + j] - tmp;
a[i + j] += tmp;
}
}
Complex a[maxn], b[maxn], ta[maxn], tb[maxn], tc[maxn], ans[maxn];
int aa[maxn], bb[maxn];
int main()
{
R int la, lb;
scanf("%s%s", A, B);
la = strlen(A); lb = strlen(B);
for (N = ; N < (la + lb); N <<= );
init();
std::reverse(A, A + la);
for (R int i = ; i < la; ++i) A[i] == '*' ? : aa[i] = A[i] - 'a' + ;
for (R int i = ; i < lb; ++i) B[i] == '*' ? : bb[i] = B[i] - 'a' + ; for (R int i = ; i < la; ++i) a[i].x = aa[i] * aa[i] * aa[i], a[i].y = ;
for (R int i = ; i < lb; ++i) b[i].x = bb[i], b[i].y = ;
bit_reverse(a, ta); bit_reverse(b, tb);
dft(ta); dft(tb);
for (R int i = ; i < N; ++i) ans[i] += (ta[i] * tb[i]); for (R int i = ; i < la; ++i) a[i].x = - * aa[i] * aa[i], a[i].y = ;
for (R int i = ; i < lb; ++i) b[i].x = bb[i] * bb[i], b[i].y = ;
bit_reverse(a, ta); bit_reverse(b, tb);
dft(ta); dft(tb);
for (R int i = ; i < N; ++i) ans[i] += (ta[i] * tb[i]); for (R int i = ; i < la; ++i) a[i].x = aa[i], a[i].y = ;
for (R int i = ; i < lb; ++i) b[i].x = bb[i] * bb[i] * bb[i], b[i].y = ;
bit_reverse(a, ta); bit_reverse(b, tb);
dft(ta); dft(tb);
for (R int i = ; i < N; ++i) ans[i] += (ta[i] * tb[i]); std::reverse(ans + , ans + N);
bit_reverse(ans, tc);
dft(tc);
// for (R int i = 0; i < N; ++i) printf("%lf %lf\n", tc[i].x, tc[i].y);
for (R int i = la - ; i < lb; ++i) if (fabs(tc[i].x / N) < 0.5) printf("%d ", i - la + );
return ;
}
/*
399906 399924 399942 399960 399978 399996
*/
FFT
其实这题的数据用bitset是可以水过的。不过可以卡。然后我优化了一发常数就只是最慢的数据本机3s以内了。我把代码放在这里欢迎大家来hack! O(∩_∩)O~~
#include <cstdio>
#include <cstring>
#include <bitset>
#include <algorithm> #define R register
#define maxn 500010
#define maxs 15635
//#define inline
char A[maxn], B[maxn];
/*inline bool eq(R char a, R char b)
{
return a == b || a == '*' || b == '*';
}*/
typedef unsigned uint;
int len; #define set(v, x) (v[x >> 5] |= 1u << (x & 31))
#define query(v, x) ((1u << (x & 31)) & v[x >> 5])
uint p[][][maxs];
uint aph[][maxs], ans[maxs];
inline void init(R int c)
{
R uint *t = p[c][], *tt;
for (R int i = ; i <= len; ++i) t[i] = aph[c][i];
for (R int i = ; i < ; ++i)
{
t = p[c][i]; tt = p[c][i - ];
for (R int j = ; j <= len; ++j)
t[j] = ((tt[j] >> ) | ((tt[j + ] & 1u) << ));
}
}
int cnt;
inline void bit_and(R int c, R int l)
{
R int fir = l >> ; R uint *t = p[c][l & ];
R int i = fir, j = ;
for (; i + < len; i += , j += )
{
ans[j] &= t[i];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
ans[j + ] &= t[i + ];
}
for (; i <= len; ++i, ++j) ans[j] &= t[i];
} //std::bitset<maxn> aph[26], ans;
int fail[maxn];
int r[maxn];
inline bool cmp(R int a, R int b) {return A[a] < A[b] || (A[a] == A[b] && (a & ) < (b & ));}
int main()
{
// freopen("str.in", "r", stdin);
// freopen("str.out", "w", stdout);
scanf("%s%s", A, B);
R int la = strlen(A), lb = strlen(B);
len = lb >> ;
R int xcnt = ;
for (R int i = ; i < la; ++i) xcnt += A[i] == '*';
for (R int i = ; i < lb; ++i) xcnt += B[i] == '*';
/*if (!xcnt)
{
fail[1] = 0;
for (R int i = la; i; --i) A[i] = A[i - 1];
for (R int i = lb; i; --i) B[i] = B[i - 1];
for (R int i = 2, p = 0; i <= la; ++i)
{
while (p && A[p + 1] != A[i]) p = fail[p];
A[p + 1] == A[i] ? ++p : 0;
fail[i] = p;
}
for (R int i = 1, p = 0; i <= lb; ++i)
{
while (p && A[p + 1] != B[i]) p = fail[p];
A[p + 1] == B[i] ? ++p : 0;
if (p == la)
{
printf("%d ", i - la + 1);
p = fail[p];
}
}
puts("");
return 0;
}*/
for (R int i = ; i < lb; ++i)
{
if (B[i] != '*') set(aph[B[i] - 'a'], i);
else for (R int j = ; j < ; ++j) set(aph[j], i);
set(ans, i);
}
for (R int i = ; i < ; ++i) init(i);
// fprintf(stderr, "%d %d\n", '*', 'a');
for (R int i = ; i < la; ++i) r[i] = i;
std::sort(r, r + la, cmp);
for (R int i = ; i < la; ++i)
if (A[r[i]] != '*')
bit_and(A[r[i]] - 'a', r[i]);
// ans &= (aph[A[i] - 'a'] >> i);
for (R int i = ; i + la - < lb; ++i) if (query(ans, i)) printf("%d ", i + ); puts("");
return ;
}
bitset
【BZOJ4259】 残缺的字符串的更多相关文章
- CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串
Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...
- BZOJ4259残缺的字符串
题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...
- BZOJ4259 残缺的字符串(FFT)
两个串匹配时相匹配的位置位置差是相同的,那么翻转一个串就变成位置和相同,卷积的形式. 考虑如何使用卷积体现两个位置能否匹配.一个暴力的思路是每次只考虑一种字符,将其在一个串中设为1,并在另一个串中将不 ...
- BZOJ4259:残缺的字符串(FFT)
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...
- BZOJ4259 残缺的字符串 【fft】
题目 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想 ...
- BZOJ4259: 残缺的字符串 & BZOJ4503: 两个串
[传送门:BZOJ4259&BZOJ4503] 简要题意: 给出两个字符串,第一个串长度为m,第二个串长度为n,字符串中如果有*字符,则代表当前位置可以匹配任何字符 求出第一个字符串在第二个字 ...
- BZOJ4259 残缺的字符串 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8798532.html 题目传送门 - BZOJ4259 题意 给你两个串,用其中一个来匹配另一个.问从母串的那些 ...
- [BZOJ4259]残缺的字符串
Description: 给定两个带通配符的串,求可能出现几次匹配,以及这些匹配位置 Hint: \(n \le 3*10^5\) Solution: 定义匹配函数 \(P(x)=\sum_{i=x} ...
- 2018.11.17 bzoj4259: 残缺的字符串(fft)
传送门 fftfftfft套路题. 我们把aaa ~ zzz映射成111 ~ 262626,然后把∗*∗映射成000. 考虑对于两个长度都为nnn的字符串A,BA,BA,B. 我们定义一个差异函数di ...
- BZOJ4259: 残缺的字符串(FFT 字符串匹配)
题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = ...
随机推荐
- Linx
1. 2. 2. 3. 5. Vi 猜数字 第二十个裴伯拉数字 1 1 2 3 5 8 2 3 求小于3000的裴伯拉数列 4 5 递归方式1到100 和 6 7 100 以内奇数.偶数和 8 Sss ...
- C++多线程基础学习笔记(六)
condition_variable.wait.notifiy_one.notify_all的使用方式 condition_variable:条件变量 wait:等待被唤醒 notify_one:随机 ...
- 图灵机器人API调用 C++版
这是一个非常简单的例子,作为新手的我是拿来练手的,当然也可以给和我一样的朋友一些参考. 而且图灵官网没有给出C的例子,网上一搜也是各种Java.C#甚至易语言实现,不要歧视C++好不好●︿●,就算不如 ...
- 使用GPU训练TensorFlow模型
查看GPU-ID CMD输入: nvidia-smi 观察到存在序号为0的GPU ID 观察到存在序号为0.1.2.3的GPU ID 在终端运行代码时指定GPU 如果电脑有多个GPU,Tensorfl ...
- Linux服务器Java进程突然消失排查办法
出处:JAVA进程突然消失的原因? 问题描述 在实际生产环境下,如果我们遇见Java进程突然消失,该如何去排查问题? 思路 可能有几种原因: ①.Java应用程序的问题:发生OOM导致进程Crash ...
- CSS3点击波浪按钮特效
在线演示 本地下载
- 《HTML、CSS、Javascript网页制作,从入门到精通》——第一章 HTML基础,第二章HTML基本标记
1)HTML的基本概念 HTML就一种描述性的标记语言,是文档的超文本标记语言. 基本结构为: HTML标记组成 : <标记元素> 源文件中标记是不区分大小写的. 2)编写方法: 1&g ...
- java基础2(Map)
1.请简述Map 的特点 Map每个元素由键与值两部分组成 Map键不能重复,每个键对应一个值 键和值可以为null 2.说出Entry键值对对象遍历Map集合的原理. Map中存放的是两种对象,一种 ...
- vue开大主要难点解决方式
问题:在我们那vue开发项目时,多层嵌套组件最繁琐,组件传参成最难的问题,并且对兄弟组件传参也无能为力,也会导致代码很难维护. 解决:采用vuex状态管理,把所有的事件和状态都储存在store对象中, ...
- Label 自适应文本(StoryBoard/xib)
To make your label automatically resize height you need to do following: Set layout constrains for l ...