题目链接:点击查看

题目大意:给出一个长度为 nnn 的字符串 sss 和一个长度为 mmm 的字符串 ttt,都含有通配符 ‘*’,现在问字符串 ttt 可以匹配字符串 nnn 的哪些位置

题目分析:模糊匹配的模板题,这里只记录一下公式,具体推导博客详见:
https://www.luogu.com.cn/blog/Ebola-Emperor/solution-p4173

先放两个公式:

设原模式串为 AAA,匹配串 BBB,AAA 的翻转 SSS

P(x)P(x)P(x) 为全匹配函数,若 P(x)=0P(x)=0P(x)=0 则称 BBB 以第 xxx 位结束的连续 mmm 位,与 AAA 完全匹配


普通的单模式串匹配:P(x)=T+f(x)−f(x−m)−2g(x)P(x)=T+f(x)-f(x-m)-2g(x)P(x)=T+f(x)−f(x−m)−2g(x)

其中 T=∑i=0m−1S(i)2T=\sum\limits_{i=0}^{m-1}S(i)^2T=i=0∑m−1​S(i)2,f(x)=∑i=0xB(i)2f(x)=\sum\limits_{i=0}^{x}B(i)^2f(x)=i=0∑x​B(i)2,g(x)=∑i+j=xS(i)B(j)g(x)=\sum\limits_{i+j=x}S(i)B(j)g(x)=i+j=x∑​S(i)B(j)

伪代码:

void FFT_Match(char *s1,char *s2,int m,int n)
{for(int i=0;i<m;i++) A[i].r=s1[i]-'a'+1;for(int i=0;i<n;i++) B[i].r=s2[i]-'a'+1;reverse(A,A+m);double T=0;for(int i=0;i<m;i++) T+=A[i].r*A[i].r;f[0]=B[0].r*B[0].r;for(int i=1;i<n;i++) f[i]=f[i-1]+B[i].r*B[i].r;FFT(A,len,1);FFT(B,len,1);for(int i=0;i<len;i++) g[i]=A[i]*B[i];FFT(g,len,-1);for(int x=m-1;x<n;x++){double P=T+f[x]-f[x-m]-2*g[x].r;if(fabs(P)<eps) printf("%d ",x-m+2);}
}

带通配符的单模式串匹配:P(x)=∑i+j=xS(i)3B(j)+∑i+j=xS(i)B(j)3−2∑i+j=xS(i)2B(j)2P(x)=\sum\limits_{i+j=x}S(i)^3B(j)+\sum\limits_{i+j=x}S(i)B(j)^3-2\sum\limits_{i+j=x}S(i)^2B(j)^2P(x)=i+j=x∑​S(i)3B(j)+i+j=x∑​S(i)B(j)3−2i+j=x∑​S(i)2B(j)2

伪代码:

void FFT_match(char *s1,char *s2,int m,int n)
{reverse(ss1,ss1+m);for(int i=0;i<m;i++) A[i]=(s1[i]!='*')?(s1[i]-'a'+1):0;for(int i=0;i<n;i++) B[i]=(s2[i]!='*')?(s2[i]-'a'+1):0;for(int i=0;i<len;i++) a[i]=Comp(A[i]*A[i]*A[i],0),b[i]=Comp(B[i],0);FFT(a,len,1);FFT(b,len,1);for(int i=0;i<len;i++) P[i]=P[i]+a[i]*b[i];for(int i=0;i<len;i++) a[i]=Comp(A[i],0),b[i]=Comp(B[i]*B[i]*B[i],0);FFT(a,len,1);FFT(b,len,1);for(int i=0;i<len;i++) P[i]=P[i]+a[i]*b[i];for(int i=0;i<len;i++) a[i]=Comp(A[i]*A[i],0),b[i]=Comp(B[i]*B[i],0);FFT(a,len,1);FFT(b,len,1);for(int i=0;i<len;i++) P[i]=P[i]-a[i]*b[i]*Comp(2,0);FFT(P,len,-1);for(int i=m-1;i<n;i++) if(fabs(P[i].r)<=1e-7) printf("%d ",i-m+2);
}

本题代码:(NTT实现)

// Problem: P4173 残缺的字符串
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4173
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
const int mod=998244353,G=3,Gi=332748118;
int n,m,limit = 1,L,r[N<<2],res[N<<2];
LL a[N<<2],b[N<<2],P[N<<2],A[N<<2],B[N<<2];
inline LL fastpow(LL a, LL k) {LL base = 1;while(k) {if(k & 1) base = (base * a ) % mod;a = (a * a) % mod;k >>= 1;}return base % mod;
}
inline void NTT(LL *A, int type) {for(int i = 0; i < limit; i++) if(i < r[i]) swap(A[i], A[r[i]]);for(int mid = 1; mid < limit; mid <<= 1) {    LL Wn = fastpow( type == 1 ? G : Gi , (mod - 1) / (mid << 1));for(int j = 0; j < limit; j += (mid << 1)) {LL w = 1;for(int k = 0; k < mid; k++, w = (w * Wn) % mod) {int x = A[j + k], y = w * A[j + k + mid] % mod;A[j + k] = (x + y) % mod,A[j + k + mid] = (x - y + mod) % mod;}}}
}
char s[N],t[N];
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);read(m),read(n);while(limit<=n+m) limit<<=1,L++;for(int i=0;i<limit;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));scanf("%s%s",t,s);reverse(t,t+m);for(int i=0;i<n;i++) A[i]=(s[i]!='*')?(s[i]-'a'+1):0;for(int i=0;i<m;i++) B[i]=(t[i]!='*')?(t[i]-'a'+1):0;for(int i=0;i<limit;i++) a[i]=A[i]*A[i]*A[i],b[i]=B[i];NTT(a,1);NTT(b,1);for(int i=0;i<limit;i++) P[i]=(P[i]+a[i]*b[i])%mod;for(int i=0;i<limit;i++) a[i]=A[i],b[i]=B[i]*B[i]*B[i];NTT(a,1);NTT(b,1);for(int i=0;i<limit;i++) P[i]=(P[i]+a[i]*b[i])%mod;for(int i=0;i<limit;i++) a[i]=A[i]*A[i],b[i]=B[i]*B[i];NTT(a,1);NTT(b,1);for(int i=0;i<limit;i++) P[i]=(P[i]-(2*a[i]*b[i])%mod+mod)%mod;NTT(P,-1);vector<int>ans;for(int i=m-1;i<n;i++) {if(!P[i]) {ans.push_back(i-m+2);}}cout<<ans.size()<<endl;for(auto it:ans) {printf("%d ",it);}return 0;
}

洛谷 - P4173 残缺的字符串(多项式匹配字符串-NTT)相关推荐

  1. HDU多校3 - 6975 Forgiving Matching(多项式匹配字符串)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss 和一个长度为 mmm 的字符串 ttt.规定 kkk 匹配的意思是,两个长度相同的字符串至多有 kkk 个位置是不同的,特别的, ...

  2. 洛谷 P3386 【模板】二分图匹配

    洛谷 P3386 [模板]二分图匹配 题目 题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行 ...

  3. iOS 字符串截取、iOS 字符串替换、iOS 字符串分隔、iOS 字符串匹配、截取字符串、匹配字符串、分隔字符串

    iOS之字符串截取.iOS 字符串替换.iOS字符串分隔.iOS之字符串匹配.截取字符串.匹配字符串.分隔字符串 1.iOS 字符串截取 //1.ios截取字符串NSString *string =@ ...

  4. 洛谷 P1598 垂直柱状图(输入带空格的字符串)

    P1598 垂直柱状图 菜鸟生成记(25) 这个题有点水,考察字符串的基本功(哎!就喜欢这考基本功的水题) 这一题涉及到输入带空格的字符串输入和格式化输出; 唉!只从gets死了(C11删除gets, ...

  5. 洛谷P3386:网络流之二分图匹配,最大流算法

    二分图:我的理解是,对图中的点集,可分为两个集合U和V,使得两个集合之间存在通路,且集合内部不存在通路.如上图. 匹配:两两不含公共端点的边集合M 最大匹配:边数最多的匹配 完美匹配:最大匹配的匹配数 ...

  6. iOS NSString 字符串处理:截取字符串、匹配字符串、分隔字符串

    为什么80%的码农都做不了架构师?>>>    1,截取字符串 NSString*string =@"aaabbbccc"; string = [string s ...

  7. iOS开发:字符串处理:截取字符串、匹配字符串、分割字符串

    分享一个比较基础的知识点,记录一下,以备以后使用的时候查找方便,现在岁数大了,脑子不好使了,记忆力减退,年轻人可以忽略此博客.本篇要分享的是关于iOS开发中,字符串简单处理的方法,此部分过于基础,仅作 ...

  8. iOS之字符串处理:截取字符串、匹配字符串、分隔字符串

    1.字符串的截取 //1.截取字符串NSString *string =@"123456d890"; NSString *str1 = [string substringToInd ...

  9. 洛谷P4173:残缺的字符串(FFT、通配符匹配)

    解析 通配符匹配的经典题. 设单词串为 AAA,文章串为 BBB. 把 AAA 翻转一下,判断问题就能转化为一个卷积的形式: F(p)=&i=0m−1match(Ai+1,Bp−i)F(p)= ...

最新文章

  1. C语言易错图形题--打印n行n列的空心正方形图案
  2. C语言-一维数组与指针
  3. linux怎么装mac系统,Linux/macos系统怎么安装nvm
  4. mysql xtrabackup 主从_使用 Xtrabackup 在线对MySQL做主从复制
  5. Silverlight实例教程 - Out of Browser的Debug和Notifications窗口
  6. ElasticSearch经验小结 (Based on 5.x)
  7. 【Codeforces Round #576 (Div. 2)】Rectangle Painting 1【记忆化搜索】
  8. 计算机-flash遮罩层动画,FLASH遮罩动画原理及应用
  9. GTD工具 Wunderlist使用心得总结
  10. 总结一下自学到现在的学习方法感悟
  11. 手把手教你搭建Hexo博客
  12. wamp5虚拟主机的配置
  13. 阿里云天池机器学习task3
  14. 控制仪表与计算机控制装置课程设计,控制仪表于装置课程设计报告
  15. wps中有半根横线无法选中无法删除
  16. adb remount 失败
  17. 读书有益——》关于 “雪” 的成语
  18. mysql如何按行数匹配,mysql-将许多行与SQL查询中的许多行匹配,并找到百分位数匹配?...
  19. STM32编程---FlashRAM介绍
  20. 和阿文一起学H5——如何搜到超酷的GIF素材

热门文章

  1. “脚踢各大Python Web框架”,Sanic真有这能耐么?
  2. RabbitMQ临时队列
  3. 分布式认证方案-基于session的认证方式
  4. Spring-Cloud中各个组件的职责
  5. 商品评价 - 实现分页
  6. 通过反射运行配置文件内容
  7. 使用response的outputstream
  8. 用户操作-登录流程分析
  9. 数据库-优化-数据库可以从哪几方面进行优化
  10. 数据库-优化-为什么要进行数据库优化