zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    }
    int main(){
        t=gi();while(t--)sol();
        return 0;
    }
    
    
  • 相关阅读:
    http://www.bugku.com:Bugku——SQL注入1(http://103.238.227.13:10087/)
    [笔记]一道C语言面试题:大整数乘法
    [笔记] Access Control Lists (ACL) 学习笔记汇总
    [笔记]如何将传统的回调函数转换为C#5.0支持的await格式
    6.链接与导航
    9章 下拉菜单
    11章圆角框 本章很重要 经常用到
    原来链接与导航
    7竖直排列的导航菜单
    8.水平导航菜单
  • 原文地址:https://www.cnblogs.com/Tyher/p/10051191.html
Copyright © 2011-2022 走看看