[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\n",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\n",solve(2,3));
        int re=0;
        for (int i=1;i<=lena-lenb+1;i++)
        {
            if (check(i)) re++;
        }
        printf("%d\n",re);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xxzh/p/9691942.html

时间: 2024-08-01 12:32:34

[TJOI2017] DNA 解题报告 (hash+二分)的相关文章

BZOJ 1044 木棍分割 解题报告(二分+DP)

来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3162  Solved: 1182[Submit][Status][Discuss] Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个

[codeforces 852 D] Exploration Plan 解题报告 (二分+最大匹配)

题目链接:http://codeforces.com/problemset/problem/852/D 题目大意: 有V个点,N个队伍,E条边,经过每条边有个时间,告诉你初始N个队伍的位置,求至少有K个队伍在不同的点的最短时间 题解: 我们二分答案时间,显然具有单调性.先floyd预处理两点之间的最短路,二分答案后把每个人和他可以走到的点连起来,跑一次最大匹配.若最大匹配数大于等于k,说明当前答案小了,否则大了 (每个匹配相等于一个人和他最终去的位置) #include<algorithm>

SA 例题泛做 解题报告

5月18日下午听了xMinh老师的讲课,作为一个认真听课的好学生,当然要做解题报告了.——题记 Poj 1743 Musical Theme 题目大意:给出 n 个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于 5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 解题报告:差分,二分长度 k,扫描 hight 数组,若出现两个后缀的 LCP 长度 >= k 且 sa >= k,return true. Poj 3261 Milk Patterns 题目大意:给定一个长度为

POJ_1007:DNA Sorting解题报告

[大致题意]排列多个DNA序列,按照每个序列的"有序程度".如果一个序列已经按照字母顺序排好了,那么这个序列有序程度最高,如AACCGGTT.反之,如果一个序列越无序,那么它的有序程度越低,如TGTCAA. [解题思路]计算每个序列的"逆序数",即反序字母对的个数,如ATGC的逆序数是3,因为TG,TC,GC都是逆序的.然后按照每个序列的逆序数排序,逆序数越大说明这个序列越无序. #include <iostream> #include <algo

pat解题报告【1078】

1078. Hashing (25) 时间限制 100 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers.  The hash fun

poj 3020 Antenna Placement 解题报告

题目链接:http://poj.org/problem?id=3020 题目意思:首先,请忽略那幅有可能误导他人成分的截图(可能我悟性差,反正有一点点误导我了). 给出一幅 h * w 的图,  “ * ” 表示 point of interest,“ o ” 忽略之.你可以对 " * " (假设这个 “* ”的坐标是 (i, j))画圈,每个圈只能把它四周的某一个点括住(或者是上面(i-1, j) or 下面(i+1, j) or 左边(i, j-1)  or 右边(i, j+1))

【未完成0.0】Noip2012提高组day2 解题报告

第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一行,包含两个正整数a, b,用一个空格隔开. 输出格式 输出只有一行,包含一个正整数x0,即最小正整数解.输入数据保证一定有解. 样例1 样例输入1 3 10 样例输出1 7 限制 每个测试点1s 提示 对于40%的数据,2 ≤b≤ 1,000: 对于60%的数据,2 ≤b≤ 50,000,000:

常州培训 day3 解题报告

第一题: 给出数轴正半轴上N个点的坐标和其权值,给出初始体力值M,人一开始在位置0,体力值会随着走过路程的增加而增加,走多少个单位的路消耗多少体力值.到每个点可以打掉,消耗的体力值就是其权值.求 最多能打掉多少点. N<=10000,其他<=10^18; 解题过程: 1.一开始就直接想到是贪心,首先人是不可能往左走的,否则不会最优.枚举最后停在哪个点,减去到这个点需要的体力,然后把这个点之前的所有点(包括这个店)的权值排个序,从小到大一个一个打,打到体力没有为止.复杂度分析:枚举N次,每次快拍

【百度之星2014~复赛)解题报告】The Query on the Tree

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~复赛)解题报告]The Query on the Tree>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=673 前言