TJOI2017DNA
- P3763 [TJOI2017]DNA
- 字符串匹配,字符集大小为\(4\),认为相差不超过\(3\)即合法。
- 对每一种字符分开考虑不同产生的贡献。
- 对于串\(S\),如果当前位置相同则\(S_i=1\),否则\(S_i=0\)。
- 对于串\(T\)则相反。
- 这样就保证了如果\(S\)串是字符\(str\),但是\(T\)串不是,那么就会产生\(1\)的贡献。
- 然后\(ntt\)即可,不开\(O2\)要\(t\)成暴力,卡了好久。
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define R register int
#define ll long long
#define il inline
using namespace std;
const int N=100001;
const int M=300001;
const int mod=998244353;
const int Gi=3;
int t,n,m,inv,f[M],g[M],h[M],er,ans,lim=1,rd[M];
char S[N],T[N];
int Qpow(R x,R y){
R ans=1,bas=x;
while(y){
if(y&1)ans=1ll*ans*bas%mod;
bas=1ll*bas*bas%mod,y>>=1;
}return ans;
}
int gi(){
R x=0,k=1;char c=getchar();
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
if(c=='-')k=-1,c=getchar();
while(c<='9'&&c>='0')x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*k;
}
void ntt(R *A,R op){
for(R i=0;i<lim;++i)if(i<rd[i])swap(A[i],A[rd[i]]);
for(R mid=1;mid<lim;mid<<=1){
R Wn=Qpow(Gi,(mod-1)/(mid<<1));
if(op==-1)Wn=Qpow(Wn,mod-2);
for(R len=mid<<1,j=0;j<lim;j+=len){
R W=1;
for(R k=0;k<mid;++k,W=1ll*W*Wn%mod){
R x=A[j+k],y=1ll*W*A[j+k+mid]%mod;
A[j+k]=(x+y)%mod,A[j+k+mid]=(x-y+mod)%mod;
}
}
}
}
void Do(char p){
for(R i=0;i<lim;++i)f[i]=g[i]=0;
for(R i=0,j=n-1;i<n;++i,--j)f[j]=(S[i]==p);
for(R i=0;i<m;++i)g[i]=(T[i]!=p);
ntt(f,1),ntt(g,1);
for(R i=0;i<lim;++i)f[i]=1ll*f[i]*g[i]%mod;
ntt(f,-1);
for(R i=0;i<lim;++i)h[i]=h[i]+1ll*f[i]*inv%mod;
}
void sol(){
scanf("%s",T),scanf("%s",S);
n=strlen(S),m=strlen(T),ans=er=0,lim=1;
while(lim<n+m)er++,lim<<=1;
for(R i=0;i<lim;++i)h[i]=0,rd[i]=(rd[i>>1]>>1)|((i&1)<<(er-1));
if(!inv)inv=Qpow(lim,mod-2);
Do('A'),Do('C'),Do('G'),Do('T');
for(R i=n-1;i<m;++i)ans+=(h[i]<=3);
printf("%d\n",ans);
}
int main(){
t=gi();while(t--)sol();
return 0;
}
TJOI2017DNA的更多相关文章
- BZOJ4892 Tjoi2017dna(后缀数组)
对每个子串暴力匹配至失配三次即可.可以用SA查lcp.然而在bzoj上被卡常了.当然也可以二分+哈希或者SAM甚至FFT. #include<iostream> #include<c ...
- [JZOJ5897]密匙--哈希骚操作
[JZOJ5897]密匙--哈希骚操作 题目链接 太懒了自行Google 前置技能 二分/倍增求LCP e.g TJOI2017DNA 分析 这题看了样例解释才知道什么意思 本以为自己身为mo法师蛤希 ...
- FFT专练
就多项式乘法这个地方不太熟 再多巩固一下. LINK:[ZJOI2014力](https://www.luogu.com.cn/problem/P3338) 把$(j-i)^2$看成一个函数 可以发现 ...
随机推荐
- WPF复杂形状按钮
方法很简单,将图片转换为<path>就可以了(需要用到Photoshop) 不过一般情况下制作按钮都不会用到这种方法,通常只要用image填充一张图片或者把路径转成按钮控件就可以了. 之所 ...
- Cinder LVM backend cinder-volume service down
目录 文章目录 目录 问题 调查 解决 问题 [stack@manager ~]$ cinder service-list +------------------+------------------ ...
- nginx代理,负载均衡
#代理,如:通过代理实现访问百度(单个机器)创建vim proxy.conf内容如下server { listen 80; server_name www.baidu.com; location / ...
- CTF—WEB—sql注入之宽字节注入
宽字节注入 宽字节注入是利用mysql的一个特性,mysql在使用GBK编码(GBK就是常说的宽字节之一,实际上只有两字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字 ...
- python--006
一.函数的作用域 1.作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变 例一: name='alex' def foo(): name='lhf' def bar(): print(na ...
- 《Python编程从0到1》笔记1——表达式的风格(前缀、中缀、后缀)
运算符和运算数组成表达式.运算符和运算数的出现次序会影响表达式乃至程序设计语言的风格. 1.前缀表达式 前缀,是指运算符的位置在前.前缀风格的一个例子是函数调用,如求最大值函数:max(3, 2, 5 ...
- excel常用公式--时间序列类
year,month,day:返回对应于某个日期的年月日.Year作为1900 - 9999之间的整数返回. weekday:返回对应于某个日期的一周中的第几天. WEEKNUM:返回特定日期的周数. ...
- P1142轰炸
这是uva上的一道模拟题. 首先给出n(n<=700)个点的坐标(坐标在1*10^9)之内,询问走直线可以经过的点数.一开始我想到了一个类似于桶排序的方法来存坐标,但是要注意数组大小啊!第二次想 ...
- python:count 函数
API 一.string 中 某字符 的次数 str.count(sub, start= 0,end=len(string)) Args Annotations sub 搜索的子字符串 start 字 ...
- centos部署LVS负载均衡直接路由DR模式
环境: 在vm里开三个虚拟机 负载调度器:10.0.3.102 真实服务器1:10.0.3.103 真实服务器2:10.0.3.104 虚拟ip: 10.0.3.99 (用来飘移) 负载调度器上 if ...