洛谷P4173 残缺的字符串(FFT)】的更多相关文章

题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 \(p\),目标串为 \(t\),将两个串的内容都根据字母先后顺序映射到 \(1\) 到 \(26\). 如果不带有通配符,那么 \(t\) 以第 \(k\) 位结束的长度为 \(|p|\) 的子串与 \(p\) 匹配时有 \[\sum_{i=0}^{|p|-1} (p[i] - t[k - |p…
传送门 话说为什么字符串会和卷积扯上关系呢……到底得脑洞大到什么程度才能想到这种东西啊……大佬太珂怕了…… 因为通配符的关系,自动机已经废了 那么换种方式考虑,如果两个字符串每一位对应的编码都相等,那么这两个字符串相等 编码相等就代表$\sum_{i=1}^na[i]-b[i]=0$ 然而这是不对的,有可能前面少一点,后面多一点,最好加起来还是$0$ 那就平方一下$\sum_{i=1}^n(a[i]-b[i]=0)^2=0$,那就大丈夫了 于是我们得到了比一位一位匹配更麻烦的方法 看到平方……把…
(不知道xjb KMP可不可以做的说) (假设下标都以0开头) 对于有一定偏移量的序列的 对应位置 匹配或者数值计算的题,这里是有一种套路的,就是把其中一个序列翻转过来,然后卷积一下,所得到的新序列C的每一个位置就包含了 所有原来一定偏移量的位置的乘积和. 对于这个题,我们只需要找到一种方法,使相同的字符代表的数乘积是一个特殊的值,然后*可以看成0(*可以匹配任意字符),这样使得卷积后的位置是特殊值的就可以匹配. 而且这种特殊值需要满足: 两个特殊值相加之后还是特殊值,两个不是特殊值相加还不是特…
题目大意: 两个带通配符的字符串\(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\)…
P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C(x,y) =A(x)- B(y)\),若为0,表示B串中以第\(y\)个字符结尾的字符可以与A串中以\(x\)节为结尾的字符可以匹配 \(P(x) = \sum_{i = 0}^{m - 1}C(i,x - m + i + 1)\) 但是很遗憾当\(P(x)\),等于零时,只能够说明上述子串的字符…
P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1-i)-B(x-(m-1-i))]^2A(m-1-i)B(x-(m-1-i))]\),展开之后化简为\(P(x)=\sum_{i+j=x}A^3(i)B(j)-2\sum_{i+j=x}A^2(i)B^2(j)+\sum_{i+j=x}A(i)B^3(j)\) 做三次FFT即可,然后交题就出了一堆玄…
题意:给你两个字符串,问你第一个在第二个中出现过多少次,并输出位置,匹配时是模糊匹配*可和任意一个字符匹配 题解:fft加速字符串匹配; 假设上面的串是s,s长度为m,下面的串是p,p长度为n,先考虑没有*的情况那么\(\sum_{j=1}^m(s_{i+j}-p_j)^2=0\)就表示能够从i开始匹配,现在考虑有*的情况,我们只需要让有*的和任意字符匹配即可,那么把公式变成\(\sum_{j=1}^m(s_{i+j}-p_j)^2*s_{i+j}*p_j)=0\),但是fft正向匹配太慢了,我…
luoguP4173 残缺的字符串 FFT 链接 luogu 思路 和昨天做的题几乎一样. 匹配等价于(其实我更喜欢fft从0开始) \(\sum\limits_{i=0}^{m-1}(S[i+j]-T[i])^2*T[i]*S[i]=0\) 展开得到 \(\sum\limits_{i=0}^{m-1}S_{i+j}^3T_{i}+\sum\limits\S_{i+j}T_{i}^3-2\sum\limits\S_{i+j}^2T_{i}^2=0\) 反转T串串 \(\sum\limits_{i…
4259: 残缺的字符串 题意:s,t,星号任意字符,匹配方案数 和上题一样 多乘上一个\(a_{j+i}\)就行了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N=(1<<20)+5;…
题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #include <cmath> #include <cctype> #include <cstdio> #include <algorithm> #define gc() getchar() const int N=1e6+5; const double PI=acos(…
BZOJ原题链接 洛谷原题链接 可以将\(1\)和\(0\)的个数和看成是\(x\)轴坐标,个数差看成\(y\)轴坐标. 向右上角走,即\(x\)轴坐标\(+1\),\(y\)轴坐标\(+1\),表示这一位为\(1\). 向右下角走,即\(x\)轴坐标\(+1\),\(y\)轴坐标\(-1\),表示这一位为\(1\). 若不考虑题目中的限制,那么这就相当于从\((0, 0)\)出发,走\(n + m\)步到达\((n + m, n - m)\). 相当于从\(n + m\)步中选出\(n\)步向…
[BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想对这两个串重新进行匹配,其中A为模板串,那么现在问题来了,请回答,对于B的每一个位置i,从这个位置开始连续m个字符形成的子串是否可能与A串完全匹配? Input 第一行包含两个正整数m,n(1<=m<=n<=300000),分别表示A串和B…
卡特兰数 参考博客 介绍 卡特兰数为组合数学中的一种特殊数列,用于解决一类特殊问题 设\(f(n)\)为卡特兰数的第n项 其通项公式为 \[f(n)=\frac{2n\choose n}{n+1} \] 关于它的证明 当然也有递推式 \[f(n)=\sum\limits_{i=0}^{n-1}f(i)\ast f(n-i-1) \] 最常用的则是对于通项的变形式 \[f(n)={2n\choose n}-{2n\choose n-1} \] 在此给出一较易的证明 例题 我们来看一道例题洛谷 p1…
洛谷 这题一看就是卡塔兰数. 因为\(cnt[1] \leq cnt[0]\),很显然的卡塔兰嘛! 平时我们推导卡塔兰是用一个边长为n的正方形推的, 相当于从(0,0)点走到(n,n)点,向上走的步数不能超过向右走,求出的方案数就是卡塔兰数. 即总方案\(-\)不合法方案 -> \(\frac{C_{2n}^{n}}{n+1}\). 这题只是改成了从(0,0)走到(n,m)点,那么就是:\(C^{m+n}_{n}-C^{m-1}_{m+n}\). 因为涉及到除法取模,所以要求逆元. 刚刚好201…
题目描述 输入两个01串,输出它们的最长公共子序列的长度 输入输出格式 输入格式: 一行,两个01串 输出格式: 最长公共子序列的长度 输入输出样例 输入样例#1: 复制 01010101010 00000011111 输出样例#1: 复制 6 说明 01串长度≤10000 数据好水啊 一开始想了一个dp[i]表示以b中到达i位置最长的LCS,f[i]表示他的位置,然后转移就好,不过这样只能处理LCS是从1开始的情况 比如 01110 101100这个数据就过不去了, 然而.. 我得了90...…
题目大意:给定一个文本串和一个模板串,串中含有通配符,求文本串中有多少个位置可以与文本串完全匹配. 题解:利用卷积求解字符串匹配问题. 通配符字符串匹配的数值表示为 \[\sum\limits_{i = 0}^{m - 1}(a[i] - b[i + k])^2 a[i]b[i + k]=0\].直接展开之后计算三个卷积即可. 需要注意的是:并不是所有 a[i] b[i + k] 均为循环卷积,是否需要倍增取决于是否成环. 代码如下 #include <bits/stdc++.h> using…
题面 传送门:洛咕 Solution 这题我写得脑壳疼,我好菜啊 好吧,我们来说正题. 这题.....emmmmmmm 显然KMP类的字符串神仙算法在这里没法用了. 那咋搞啊(或者说这题和数学有半毛钱关系啊) 我们考虑把两个字符相同强行变为一个数学关系,怎么搞呢? 考虑这题是带通配符的,我们可以这样设: \(C(x,y)=(A[x]-B[y])^2*A[x]*B[y]\) 因此,我们可以看出两个字符一样当且仅当\(C(x,y)=0\) 因此,我们再设一个函数\(P(x)\)表示\(B\)串以第\…
[Luogu4173] 题解 \(1.\)定义匹配函数 \(2.\)定义完全匹配函数 \(3.\)快速计算每一位的完全匹配函数值 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #define debug(...) fprintf(stderr,__VA_ARGS__) #define Debug(x) cout&l…
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想对这两个串重新进行匹配,其中A为模板串,那么现在问题来了,请回答,对于B的每一个位置i,从这个位置开始连续m个字符形成的子串是否可能与A串完全匹配? Input 第一行包含两个正整数m,n(1<=m<=n<=300000),分别表示A串和B串的长度. 第二行为一个长度为m的…
[题意]给定长度为m的匹配串B和长度为n的模板串A,求B在A中出现多少次.字符串仅由小写字母和通配符" * "组成,其中通配符可以充当任意一个字符.n<=3*10^5. [算法]FFT [题解]假设模板串的数组A用0~26代表所有字符,0为通配符,匹配串的数组B同理,那么用表示差异的经典套路: $$C_n=\sum_{i=0}^{m-1}(A_{n+i}-B_i)^2*A_{n+i}*B_i$$ 那么可以看出$C_n=0$当且仅当$S_A[n,n+m-1]=S_B[0,m-1]$…
传送门 两种做法,一种是依次考虑每种字符,然后如果某个位置是该字符或者是\(*\)对应的值就是1,否则是0,然后把第一个串倒过来,fft卷积起来,最后看对应位置的值是否为m 然而上面那个做法在字符集大小过大的时候会GG,所以考虑一次性匹配,如果不考虑通配符\(*\),设(开头)位置i的匹配函数为\(f(i)=\sum_{j=1}^{m}(a_j-b_{i+m-j})^2\),\(f(i)=0\)说明i可以匹配 因为通配符可以匹配任何字符,也就是会让某组匹配一定是0,那么\(f(i)\)可以改成\…
题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = 0\) 那么说明能匹配.然后拆开三波FFT就行了 /* */ #include<bits/stdc++.h> #define LL long long const int MAXN = 1e6 + 10, INF = 1e9 + 7; using namespace std; inline in…
传送门 考虑如何使用FFT计算两个子串是否匹配.如果字符集比较小可以把每个字符都拿出来暴力做一遍,但是字符集比较大的时候复杂度就会有问题.这个时候可以考虑匹配函数. 先考虑没有通配符的情况.将\(A\)串翻转,然后设匹配函数\(chk(i,j) = (A_i - B_j)^2\).不难知道\(A_i = B_j \Leftrightarrow chk(i,j) = 0\). 又设\(C(x) = \sum\limits_{i=1}^m chk(m + 1 - i , x + i - 1)\),那…
P3989 [SHOI2013]阶乘字符串 题目描述 给定一个由前\(n(\le 26)\)个小写字母组成的串\(S(|S|\le 450)\).串\(S\)是阶乘字符串当且仅当前 \(n\) 个小写字母的全排列(共\(n!\)种)都作为的子序列(可以不连续)出现. 请判断出给定的串是否是阶乘字符串. 当\(n> 21\)时无解,原因不明,留坑 剩下的状压一下就好了 \(dp_s\)表示集合\(s\)的所有排列出现的最前位置 枚举集合最后一个元素更新 \(yuu_{i,j}\)表示\(j\)在\…
题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确. A++语言的循环结构如下: F i x y 循环体 E 其中F i x y表示新建变量 ii(变量 ii 不可与未被销毁的变量重名)并初始化为 xx, 然后判断 ii 和 yy 的大小关系,若 ii 小于等于 yy 则进入循环,否则不进入.每次循环…
又是一道FFT套路题 思路可以参考bzoj4503,题解 我们对串S和串T中出现的*处全部赋值为0. 反正最终的差异度式子大概就是 $C[i]=\sum_{j=0}^{|T|-1}S[i+j]T[j](S[i+j]-T[j])^2$ 然后和上一题一样的展开方式,将T串reverse一下做FFT再统计下即可. 然后这题卡常,FFT的长度是100W,所以用NTT会被卡常(我就T了) 然后就没了 #include<bits/stdc++.h> #define PI acos(-1) #define…
题目链接 题意分析 啥 ? ? ? \(FFT\)做字符串匹配 可是就是这样 我们定义匹配函数 我们定义\(A\)是匹配串 \(B\)是被匹配串 我们当前到达\(B\)串的\(x\)位置 \[P(x)=\sum_{i=0}^{m-1}[A(i)-B(x-m+i+1)]\] 那么如果\(P(x)=0\)的话 是不是就是匹配上了呢? ? 不是 如果匹配的是\(ab\)以及\(ba\)的话 那么就\(WA\)了 所以我们令 \[P(x)=\sum_{i=0}^{m-1}[A(i)-B(x-m+i+1)…
https://www.luogu.org/problem/show?pid=3709 题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S 如果S为空,你rp减1 如果S中有一个元素不小于x,则你rp减1,清空S 之后将x插入S 由于你是大爷,平时做过的题考试都会考到,所以每次询问…
题目描述 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4时,4个整数7,13,4,246联接成的最大整数为:7424613 输入输出格式 输入格式: 第一行,一个正整数n. 第二行,n个正整数. 输出格式: 一个正整数,表示最大的整数 输入输出样例 输入样例#1: 3 13 312 343 输出样例#1: 34331213 [分析]: 首先我们可以证明最大的答案字典序也一定最大…
题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S 如果S为空,你rp减1 如果S中有一个元素不小于x,则你rp减1,清空S 之后将x插入S 由于你是大爷,平时做过的题考试都会考到,所以每次询问你搞完这段区间的字符之后最多还有多少rp?rp初始为0 询问之间不互相影响~ 输入输出格…