zoukankan      html  css  js  c++  java
  • [TJOI2017] DNA 解题报告 (hash+二分)

    题目链接:https://www.luogu.org/problemnew/show/P3763

    题目大意:

    给定原串S0,询问S0有多少个子串和给定串S相差不到3个字母

    题解:

    我们枚举S0的子串,问题转化为如何高效的判断两个串是否相差不到三个字母

    考虑到数据范围,发现只能有log的时间余地

    自然想到二分

    solve每次找到第一个不同的位置并且返回,连续solve 4次,若S在这期间被处理完了,那么说明两个串相差不到3个字母

    当然还有一些小细节

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    typedef unsigned long long ull;
    const int N=1e5+15; 
    int lena,lenb;
    ull pin[N],haa[N],hab[N];
    char a[N],b[N];
    void H()
    {
        haa[0]=hab[0]=0;
        for (int i=1;i<=lena;i++)
        {
            haa[i]=haa[i-1]*113+a[i]-'a';
        }
        for (int i=1;i<=lenb;i++)
        {
            hab[i]=hab[i-1]*113+b[i]-'a';
        }
    }
    int solve(int x,int y)
    {
        int l=1,r=lenb;
        while (l<r)
        {
            int mid=l+r>>1;
            if ((haa[x+mid-1]-haa[x-1]*pin[mid])==(hab[y+mid-1]-hab[y-1]*pin[mid]))
            {
                l=mid+1;
            }
            else r=mid;
        }
        if (haa[x+l-1]-haa[x-1]*pin[l]!=hab[y+l-1]-hab[y-1]*pin[l])
        {
            return l;
        }
        else return l+1;
    }
    int check(int x)
    {
        int now=1,k; 
        for (int i=1;i<=3;i++)
        {
            k=solve(x,now);
            //printf("%d %d %d
    ",x,now,k);
            x+=k;now+=k;
            if (now>lenb) return 1;
        }
        k=solve(x,now);
        x+=k-2;now+=k-2;
        if (now>=lenb) return 1;
        return 0;
    }
    int main()
    {
        pin[0]=1;
        for (int i=1;i<=N;i++) pin[i]=pin[i-1]*113;
        int T;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%s",a+1);
            scanf("%s",b+1);
            lena=strlen(a+1),lenb=strlen(b+1);
            H();
            //printf("%d
    ",solve(2,3));
            int re=0;
            for (int i=1;i<=lena-lenb+1;i++)
            {
                if (check(i)) re++;
            }
            printf("%d
    ",re);
        }
        return 0;
    }
  • 相关阅读:
    HDU 4069 Squiggly Sudoku
    SPOJ 1771 Yet Another NQueen Problem
    POJ 3469 Dual Core CPU
    CF 118E Bertown roads
    URAL 1664 Pipeline Transportation
    POJ 3076 Sudoku
    UVA 10330 Power Transmission
    HDU 1426 Sudoku Killer
    POJ 3074 Sudoku
    HDU 3315 My Brute
  • 原文地址:https://www.cnblogs.com/xxzh/p/9691942.html
Copyright © 2011-2022 走看看