洛谷P4173 残缺的字符串
题目大意:
两个带通配符的字符串\(a,b\),求\(a\)在\(b\)中出现的位置
字符串长度\(\le 300000\)
考虑魔改一发\(kmp\),发现魔改不出来
于是考虑上网搜题解
然后考虑\(ntt\),发现两个串匹配需要满足\(\sum\limits_{i=0}^{n-1}(a_i-b_i)=0\)
发现不太对,可能有正有负相消等于\(0\),我们加上平方\(\sum\limits_{i=0}^{n-1}(a_i-b_i)^2=0\)
再考虑通配符,我们可以设通配符的价值为\(0\),然后变形一下\(\sum\limits_{i=0}^{n-1}a_i*b_i*(a_i-b_i)^2=0\)
展开得到\(\sum\limits_{i=0}^{n-1}a_i^3*b_i-2a_i^2*b_i^2+a_i*b_i^3\)
我们可以把这三项分开考虑
对于其中一项\(\sum\limits_{i=0}^{n-1}a_i^3*b_i\)
设\(a^{'}\)为\(a\)翻转,\(j=n-i-1\),答案为\(\sum\limits_{i=0}^{n-1}a_j^{'3}*b_i\)
然后卷起来,判断卷完之后\(i=(m-1\sim n-1)\)哪个系数是零,把\(i-m+2\)加入答案
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
inline int read()
{
int x=0;char ch,f=1;
for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
if(ch=='-') f=0,ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
}
const int N=3e5+10,p=998244353,g=3,gi=332748118;
int n,m,limit,len;
char a[N],b[N];
int pos[N<<2];
int ret[N],num;
int a1[N<<2],b1[N<<2],c[N<<2];
inline int fast(int x,int k)
{
int ret=1;
while(k)
{
if(k&1) ret=ret*x%p;
x=x*x%p;
k>>=1;
}
return ret;
}
inline void ntt(int *a,int inv)
{
for(int i=0;i<limit;++i)
if(i<pos[i]) swap(a[i],a[pos[i]]);
for(int mid=1;mid<limit;mid<<=1)
{
int Wn=fast(inv?g:gi,(p-1)/(mid<<1));
for(int r=mid<<1,j=0;j<limit;j+=r)
{
int w=1;
for(int k=0;k<mid;++k,w=w*Wn%p)
{
int x=a[j+k],y=w*a[j+k+mid]%p;
a[j+k]=(x+y)%p;
a[j+k+mid]=(x-y)%p;
if(a[j+k+mid]<0) a[j+k+mid]+=p;
}
}
}
if(inv) return;
inv=fast(limit,p-2);
for(int i=0;i<limit;++i) a[i]=a[i]*inv%p;
}
inline void work(int *a,int *b,int opt)
{
ntt(a,1);ntt(b,1);
for(int i=0;i<limit;++i) c[i]=c[i]+a[i]*b[i]*opt;
}
inline void main()
{
m=read(),n=read();
scanf("%s%s",a,b);
for(int i=0;i<m;++i)
{
if(a[i]=='*') a[i]=0;
else a[i]=a[i]-'a'+1;
}
for(int i=0;i<n;++i)
{
if(b[i]=='*') b[i]=0;
else b[i]=b[i]-'a'+1;
}
reverse(a,a+m);
for(limit=1;limit<=n+m;limit<<=1) ++len;
for(int i=0;i<limit;++i) pos[i]=(pos[i>>1]>>1)|((i&1)<<(len-1));
for(int i=0;i<m;++i) a1[i]=a[i]*a[i]*a[i];
for(int i=0;i<n;++i) b1[i]=b[i];
work(a1,b1,1);
for(int i=0;i<limit;++i) a1[i]=b1[i]=0;
for(int i=0;i<m;++i) a1[i]=a[i]*a[i];
for(int i=0;i<n;++i) b1[i]=b[i]*b[i];
work(a1,b1,-2);
for(int i=0;i<limit;++i) a1[i]=b1[i]=0;
for(int i=0;i<m;++i) a1[i]=a[i];
for(int i=0;i<n;++i) b1[i]=b[i]*b[i]*b[i];
work(a1,b1,1);
ntt(c,0);
for(int i=m-1;i<n;++i)
{
if(!c[i]) ret[++num]=i-m+2;
}
printf("%lld\n",num);
for(int i=1;i<=num;++i) printf("%lld ",ret[i]);
}
}
signed main()
{
red::main();
return 0;
}
洛谷P4173 残缺的字符串的更多相关文章
- 洛谷 P4173 残缺的字符串 (FFT)
题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 ...
- 洛谷P4173 残缺的字符串(FFT)
传送门 话说为什么字符串会和卷积扯上关系呢……到底得脑洞大到什么程度才能想到这种东西啊……大佬太珂怕了…… 因为通配符的关系,自动机已经废了 那么换种方式考虑,如果两个字符串每一位对应的编码都相等,那 ...
- 洛谷 P4173 残缺的字符串
(不知道xjb KMP可不可以做的说) (假设下标都以0开头) 对于有一定偏移量的序列的 对应位置 匹配或者数值计算的题,这里是有一种套路的,就是把其中一个序列翻转过来,然后卷积一下,所得到的新序列C ...
- Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用
P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...
- P4173 残缺的字符串(FFT字符串匹配)
P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1 ...
- BZOJ1856或洛谷1641 [SCOI2010]生成字符串
BZOJ原题链接 洛谷原题链接 可以将\(1\)和\(0\)的个数和看成是\(x\)轴坐标,个数差看成\(y\)轴坐标. 向右上角走,即\(x\)轴坐标\(+1\),\(y\)轴坐标\(+1\),表示 ...
- 卡特兰数 洛谷P1641 [SCOI2010]生成字符串
卡特兰数 参考博客 介绍 卡特兰数为组合数学中的一种特殊数列,用于解决一类特殊问题 设\(f(n)\)为卡特兰数的第n项 其通项公式为 \[f(n)=\frac{2n\choose n}{n+1} \ ...
- 洛谷 P1641 [SCOI2010]生成字符串
洛谷 这题一看就是卡塔兰数. 因为\(cnt[1] \leq cnt[0]\),很显然的卡塔兰嘛! 平时我们推导卡塔兰是用一个边长为n的正方形推的, 相当于从(0,0)点走到(n,n)点,向上走的步数 ...
- 洛谷P1852 奇怪的字符串
题目描述 输入两个01串,输出它们的最长公共子序列的长度 输入输出格式 输入格式: 一行,两个01串 输出格式: 最长公共子序列的长度 输入输出样例 输入样例#1: 复制 01010101010 00 ...
随机推荐
- bzoj5219 [Lydsy2017省队十连测] 最长路径
题意: 做法来自 首先竞赛图缩点后是一条链,\(1\)号节点在开头的那个\(SCC\)中,因此从\(1\)号节点出发的最长链即为\(1\)号节点所在的\(SCC\)的大小\(+1\)号节点拓扑序之后的 ...
- Collection接口综述
Collection接口 Collection是集合类基本的接口,它不提供具体的实现,集合类都继承自Collection接口,Collection代表的是一种规则,它包含的元素必须符合某种规则,比如有 ...
- H3C DRNI学习
DRNI:Distributed Resilient Network Interconnect,分布式弹性网络互连.DR:分布式聚合接口IPP:内部控制链路端口IPL:内部控制链路DRCP报文:分布式 ...
- Rust对协程的思考
最近和同事聊起来,觉得lua缺乏编译型语言的类型校验功能,还有变量拼写检查之类的,导致线上总是有低级错误出现.比如最近有一个是变量名拼写少了一个字母,导致某功能没开启:还有一个是变量传参时,之前测试多 ...
- Spring框架的相关介绍
Spring是一个开源轻量级的框架,它的核心是控制反转(IOC)和面向切面编程(AOP). 作为业务层框架的spring能够很好地整合表现层跟持久层. IOC:将类的创建和依赖关系写到配置文件里,可以 ...
- 自定义异常类;键盘输入;try catch用法
相关考点:自定义异常类:键盘输入:try catch用法 1.设计一个java程序,自定义一个异常类,从键盘输入一个字符串,如果等于“abc”,则抛出异常. public class MyExcept ...
- SpringBoot2.0中的事务@Transactional
在SpringBoot2.0中使用使用需要注意的地方. 1. 加@Transactional的方法不能是private和protected修饰,private会直接报编译错误,protected不会报 ...
- jxl解析excel时,处理中文乱码问题
jxl解析excel时,处理中文乱码问题 一般出现较多的问题是,当exce中包含了中文或特殊字符时,在解析时候就会出现乱码现象. 解决方法为: InputStream in = new FileInp ...
- 2018-2-13-win10-uwp-手动锁Bitlocker
原文:2018-2-13-win10-uwp-手动锁Bitlocker title author date CreateTime categories win10 uwp 手动锁Bitlocker l ...
- 移动端适配方案(rem+flex)
为什么用rem不用px? 主流:各大网站的移动版绝大多数都是用的rem. 移动端屏幕分辨率差别太大:最低适配的iPhone6,分辨率仅为750*1334.而现在市面上大多数手机,都达到了1080* ...