zoukankan      html  css  js  c++  java
  • [CF528D]Fuzzy Search【FFT】

    [CF528D]Fuzzy Search
    给定母串(S)和模式串(T),字符集大小为(4),给定(k)(T)在某个位置(i)匹配,当且仅当(forall; jin [0, |T|-1], exists pin [i-k, i+k])使得(T_j=S_{i+p+j}),求(T)的匹配次数
    (|S|, |T|le 2*{10}^5)
    (|T|=m),
    对于每个字符(c),令(a[i]=[S_i)能匹配(c])(b[i]=[T_i == c])
    贡献(f[j]=sum_{i=0}^{m-1}a[j+i]*b[i]),当总贡献为(m)(j)位置为匹配位置
    (d[i]=b[m-i-1]),即(d[m-i-1]=b[i]),
    则$$f[j]=sum_{i=0}^{m-1}a[j+i]d[m-i-1]=(ad)(j+m-1)$$
    计算卷积就好

    char s[Maxn], t[Maxn];
    int q[Maxn], head, tail, tot[Maxn];
    void cal(char c){
    	memset(f, 0, sizeof(f)); memset(g, 0, sizeof(g));
    	head=1, tail=0;
    	for(int i=0; i < n; i++){
    		if(s[i] == c) q[++tail]=i;
    		while(head <= tail && q[head]+k < i) head++;
    		if(head <= tail) f[i].a=1;
    	}head=1, tail=0;
    	for(int i=n-1; i >= 0; i--) {
    		if(s[i] == c) q[++tail]=i;
    		while(head <= tail && q[head] > i+k) head++;
    		if(head <= tail) f[i].a=1;
    	}
    	for(int i=0; i < m; i++) if(t[i] == c) g[m-i-1].a=1;
    	FFT(f, 1); FFT(g, 1); for(int i=0; i < lim; i++) f[i]=f[i]*g[i]; FFT(f, -1);
    	for(int i=0; i < n; i++) tot[i]+=floor(f[i+m-1].a/lim+0.5);
    }
    
    void solve(){
    	n=read(), m=read(), k=read(); scanf("%s", s); scanf("%s", t);
    	while(lim <= n+m-2) lim<<=1, l++;
    	for(int i=0; i < lim; i++) r[i]=r[i>>1]>>1|((i&1)<<l-1);
    	cal('A'); cal('G'); cal('C'); cal('T'); int ans=0;
    	for(int i=0; i < n; i++) if(tot[i] >= m) ans++;
    	printf("%d", ans);
    }
    

    (我真是个小天才,用(char)来存数组(orz)

  • 相关阅读:
    通过Math.atan2计算角度 改变物体朝向
    table.sort 排序的问题
    shader 实现正旋波效果 水面波动效果
    第一篇碎碎心得
    ping 整理
    路由器
    C语言里如何读取位数据的某几位?
    ubunut命令
    基于SPIflash 的fatfs调试步骤
    makefile 学习总结--函数
  • 原文地址:https://www.cnblogs.com/zerolt/p/9303013.html
Copyright © 2011-2022 走看看