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$看成一个函数 可以发现 ...
随机推荐
- redis详解及应用(雪崩、击穿、穿透)
一. redis的简介与安装 引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/ 二. redis的配置文件介绍 引用:ht ...
- Linux配置全局jdk以及Tomcat服务器简单测试
Linux配置全局jdk 1.确保相应文件夹下有apache-tomcat和jdk的压缩文件 注意:jdk文件必须为适应Linux版本的文件 (如果已经有了相应文件,可以跳过以下第2-3个步骤) 2. ...
- opencv的曲线拟合polyfit
推荐一个不错的网页,可以直接用solve函数求解方程组: http://m.blog.csdn.net/u014652390/article/details/52789591 4.1 曲线拟合的最小二 ...
- js获取当天时间,7天前后时间,时间格式化
格式化时间年月日时分秒 //时间戳转换方法 date:时间戳数字 formatDate(date) { var date = new Date(date); var YY = date.getFull ...
- python基础学习笔记-切片难点
numbers = [1,2,3,4,5,6,7,8,9,10] print(numbers[5::-2]) print(numbers[10:5:-2]) print(numbers[:5:-2]) ...
- cocos2dx[3.2](5) 屏幕适配
1.两个分辨率 1.1.窗口分辨率 在AppDelegate.cpp中有个设置窗口分辨率的函数.该函数是设置了我们预想设备的屏幕大小,也就是应用程序窗口的大小. // glView->setFr ...
- python学习之不要在列表迭代的时候进行增删操作
注意:列表不能在for循环时使用remove方法 li = [11,22,33,44] for i in li : li.remove(i) print (li) #输出 [22, 44] for ...
- shell脚本判断里面的字符含义
[ -s FILE ] 如果 FILE 存在且大小不为0则为真. [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c ...
- js 数组去重方法总结
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, ...
- 【VS开发】【图像处理】自动白平衡(AWB)算法---色温曲线
原文地址:http://blog.csdn.net/wzwxiaozheng/article/details/38434391 白平衡算法---色温曲线 本文大体讲解了白平衡的算法流程,适用于想了解和 ...