【bzoj4259/bzoj4503】残缺的字符串/两个串 FFT
bzoj4259
题目描述
输入
输出
样例输入
3 7
a*b
aebr*ob
样例输出
2
1 5
bzoj4503
题目描述
题解
FFT
设两个字符c1、c2的差异度为(c1-c2)^2,那么两个普通字符串能匹配,当且仅当∑(str1[i]-str2[i])^2=0
考虑包含万能字符的情况,由于可以匹配任何字符,则应当把差异度看作0。
即:万能字符为0,其它字符为1~26,差异度为c1*c2*(c1-c2)^2。
展开得c1^3*c2 - 2*c1^2*c2^2 + c1*c2^3。
令题中所给的两个字符串计算差异度,可以分成以上3部分来求,并且每部分都可以化成只包含str1和只包含str2的两个式子的乘积。
并且发现两个位置的差是定值,可以翻转后转化为卷积来求。
于是上FFT出解。
对于4503,可以少考虑一种一个字符为万能字符的情况,所以可以少FFT计算,具体见代码。
bzoj4259:
#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 1 << 20
#define pi acos(-1)
#define tra(ch) (ch == '*' ? 0 : ch - 'a' + 1)
using namespace std;
struct data
{
double x , y;
data() {x = y = 0;}
data(double x0 , double y0) {x = x0 , y = y0;}
data operator+(const data a)const {return data(x + a.x , y + a.y);}
data operator-(const data a)const {return data(x - a.x , y - a.y);}
data operator*(const data a)const {return data(x * a.x - y * a.y , x * a.y + y * a.x);}
}a1[N] , b1[N] , a2[N] , b2[N] , a3[N] , b3[N];
char sa[N] , sb[N];
int ans[N] , tot;
void fft(data *a , int n , int flag)
{
int i , j , k;
for(i = k = 0 ; i < n ; i ++ )
{
if(i > k) swap(a[i] , a[k]);
for(j = (n >> 1) ; (k ^= j) < j ; j >>= 1);
}
for(k = 2 ; k <= n ; k <<= 1)
{
data wn(cos(2 * pi * flag / k) , sin(2 * pi * flag / k));
for(i = 0 ; i < n ; i += k)
{
data t , w(1 , 0);
for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn)
t = w * a[j + (k >> 1)] , a[j + (k >> 1)] = a[j] - t , a[j] = a[j] + t;
}
}
}
void work(data *a , data *b , int len)
{
int i;
fft(a , len , 1) , fft(b , len , 1);
for(i = 0 ; i < len ; i ++ ) a[i] = a[i] * b[i];
fft(a , len , -1);
for(i = 0 ; i < len ; i ++ ) a[i].x = a[i].x / len;
}
int main()
{
int m , n , i , len;
double tmp;
scanf("%d%d%s%s" , &m , &n , sa , sb);
for(i = 0 ; i < m ; i ++ ) tmp = tra(sa[i]) , a1[m - i - 1].x = tmp , a2[m - i - 1].x = tmp * tmp , a3[m - i - 1].x = tmp * tmp * tmp;
for(i = 0 ; i < n ; i ++ ) tmp = tra(sb[i]) , b1[i].x = tmp * tmp * tmp , b2[i].x = tmp * tmp , b3[i].x = tmp;
for(len = 1 ; len < n + m ; len <<= 1);
work(a1 , b1 , len) , work(a2 , b2 , len) , work(a3 , b3 , len);
for(i = 0 ; i <= n - m ; i ++ )
if(!(int)(a1[i + m - 1].x - 2 * a2[i + m - 1].x + a3[i + m - 1].x + 0.1))
ans[++tot] = i;
printf("%d\n" , tot);
for(i = 1 ; i <= tot ; i ++ ) printf("%d " , ans[i] + 1);
return 0;
}
bzoj4503:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 1 << 20
#define tra(ch) (ch == '?' ? 0 : ch - 'a' + 1)
#define pi acos(-1)
using namespace std;
struct data
{
double x , y;
data() {x = y = 0;}
data(double x0 , double y0) {x = x0 , y = y0;}
data operator+(const data a)const {return data(x + a.x , y + a.y);}
data operator-(const data a)const {return data(x - a.x , y - a.y);}
data operator*(const data a)const {return data(x * a.x - y * a.y , x * a.y + y * a.x);}
}a1[N] , b1[N] , a2[N] , b2[N];
char sa[N] , sb[N];
int ans[N] , tot;
void fft(data *a , int n , int flag)
{
int i , j , k;
for(i = k = 0 ; i < n ; i ++ )
{
if(i > k) swap(a[i] , a[k]);
for(j = (n >> 1) ; (k ^= j) < j ; j >>= 1);
}
for(k = 2 ; k <= n ; k <<= 1)
{
data wn(cos(2 * pi * flag / k) , sin(2 * pi * flag / k));
for(i = 0 ; i < n ; i += k)
{
data t , w(1 , 0);
for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn)
t = w * a[j + (k >> 1)] , a[j + (k >> 1)] = a[j] - t , a[j] = a[j] + t;
}
}
}
void work(data *a , data *b , int len)
{
int i;
fft(a , len , 1) , fft(b , len , 1);
for(i = 0 ; i < len ; i ++ ) a[i] = a[i] * b[i];
fft(a , len , -1);
for(i = 0 ; i < len ; i ++ ) a[i].x /= len;
}
int main()
{
int la , lb , i , len;
double tmp , a3 = 0;
scanf("%s%s" , sa , sb) , la = strlen(sa) , lb = strlen(sb);
for(i = 0 ; i < la ; i ++ ) tmp = tra(sa[i]) , a1[i].x = tmp * tmp , a2[i].x = tmp;
for(i = 0 ; i < lb ; i ++ ) tmp = tra(sb[i]) , b1[lb - i - 1].x = tmp , b2[lb - i - 1].x = tmp * tmp , a3 += tmp * tmp * tmp;
for(len = 1 ; len < 2 * la || len < 2 * lb ; len <<= 1);
work(a1 , b1 , len) , work(a2 , b2 , len);
for(i = 0 ; i < la - lb + 1 ; i ++ )
if(!(int)(a1[i + lb - 1].x - 2 * a2[i + lb - 1].x + a3 + 0.1))
ans[++tot] = i;
printf("%d\n" , tot);
for(i = 1 ; i <= tot ; i ++ ) printf("%d\n" , ans[i]);
return 0;
}
【bzoj4259/bzoj4503】残缺的字符串/两个串 FFT的更多相关文章
- [bzoj4259][bzoj4503] 残缺的字符串 [FFT]
题面 传送门 bzoj上的这两题是一样的...... 正文 我看到这道题,第一想法是跑魔改过的KMP,然后很快发现不可行 于是想换个角度思考 其实,本题最大的问题就在于通配符的存在:它可以匹配任意一个 ...
- 【BZOJ4503】两个串 FFT
[BZOJ4503]两个串 Description 兔子们在玩两个串的游戏.给定两个字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有“?”字符,这个字符可以匹配任何字 ...
- 【BZOJ4259】残缺的字符串
[BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...
- 【BZOJ4259】残缺的字符串(FFT)
[BZOJ4259]残缺的字符串(FFT) 题面 给定两个字符串\(|S|,|T|\),两个字符串中都带有通配符. 回答\(T\)在\(S\)中出现的次数. \(|T|,|S|<=300000\ ...
- 【BZOJ4259】残缺的字符串 FFT
[BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...
- BZOJ4259:残缺的字符串——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4259 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度 ...
- BZOJ4259:残缺的字符串(FFT与字符串匹配)
很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想对这两 ...
- 【BZOJ4259】 残缺的字符串
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...
- BZOJ 4503: 两个串 [FFT]
4503: 两个串 题意:兔子们在玩两个串的游戏.给定两个只含小写字母的字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有"?"字符,这个字符可以匹 ...
随机推荐
- vim 编辑器的使用方法
vim 命令模式 默认打开文件为命令模式 命令行模式 shift+: 命令行模式 编辑模式 i 编辑模式 Esc 切换命令模式 命令模式 -----字符操作 i 当 ...
- 一键备份脚本 backup.sh
做网站最重要的是什么?数据!数据,是网站之本,备份,是每一个站长都应该重视的事情.但同时,备份也是一件繁琐和重复的事情.所以,这些事情,肯定能做到自动化的.下面来介绍一下这个一键备份脚本 backup ...
- 漫谈 Clustering (5): Hierarchical Clustering
系列不小心又拖了好久,其实正儿八经的 blog 也好久没有写了,因为比较忙嘛,不过觉得 Hierarchical Clustering 这个话题我能说的东西应该不多,所以还是先写了吧(我准备这次一个公 ...
- PAT (Advanced Level) Practise - 1095. Cars on Campus (30)
http://www.patest.cn/contests/pat-a-practise/1095 Zhejiang University has 6 campuses and a lot of ga ...
- 01_15_Struts2_带参数的结果集
01_15_Struts2_带参数的结果集 1. 背景说明 服务器端页面跳转的时候,通过struts提供的标签的valuestack可以直接取.服务器端的转发,valuestack的对象属性可以共享. ...
- java算法面试题:排序都有哪几种方法?请列举。用JAVA实现一个快速排序。选择冒泡快速集合至少4种方法排序
package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.Compar ...
- C#Aspose操作Word & Excel简版(后会研究补充更多功能)
利用Aspose操作Word & Excel首先要在项目中标引用Aspose.Words.dll和Aspose.Cells.dll. 首先说一说向Word中写入数据,目前做的是向Word中的标 ...
- yum 安装percona mysql 5.7
Mysql5.7安装准备 1.基础信息: (1)可参考官方文档[https://www.percona.com/doc/percona-server/5.7/installation/yum_repo ...
- Linux下重要日志及查看方式
1.Linux下重要日志文件介绍 /var/log/boot.log 该文件记录了系统在引导过程中发生的事件,就是Linux系统开机自检过程显示的信息,如图1所示: 图1 /var/log/boot. ...
- 多种方式实现依赖注入及使用注解定义bean
构造注入 如何给构造方法中的参数注入方法呢如下 首先bean代码如下 package cn.pojo; public class Greeting { /** * 说的话 */ private Str ...