首页 > 其他 > 详细

洛谷P3763 [TJOI2017]DNA

时间:2019-02-04 19:14:35      阅读:194      评论:0      收藏:0      [点我收藏+]
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 using namespace std;
 6 typedef unsigned long long ull; 
 7 const int N=100005,p=131;//p进制 hash 
 8 int T,n,ans,len1,len2;
 9 ull f[N],key1[N],key2[N];
10 char s1[N],s2[N];
11 void init(){//字符串hash 
12     memset(key1,0,sizeof(key1));//可以通过对二分和判定答案时边界的控制避免每次memset的耗时 
13     memset(key2,0,sizeof(key2));
14     for(int i=1;i<=len1;++i){
15         key1[i]=key1[i-1]*p+(ull)s1[i];
16     }
17     for(int i=1;i<=len2;++i){
18         key2[i]=key2[i-1]*p+(ull)s2[i];
19     }
20 }
21 ull query(int flag,int pos1,int pos2){//查询两个字符串中pos1到pos2的hash值 
22     if(flag==1) return key1[pos2]-key1[pos1-1]*f[pos2-pos1+1];
23     else return key2[pos2]-key2[pos1-1]*f[pos2-pos1+1];
24 }
25 int lcp(int pos1,int pos2){//二分+hash求s1串中以pos1位置开始和s2串中以pos2位置开始的lcp 
26     int l=0,r=min(len1,len2);//r设的较大 貌似可以通过计算传入r 可以避免每次求hash值时memset的时间 
27     while(l<r){
28         int mid=(l+r+1)>>1;//丑陋的二分写法... 
29         if(mid>0&&query(1,pos1,pos1+mid-1)==query(2,pos2,pos2+mid-1)) l=mid;
30         else r=mid-1;
31     }
32     return l;
33 }
34 bool check(int pos){
35     int cnt=0,pos2=1,t;
36     while(cnt<3){//跳三次还不同说明三处以上不同 
37         t=lcp(pos,pos2);//lcp 
38         pos+=t+1;//这一位不同 两个指针跳到lcp后一位 
39         pos2+=t+1;
40         if(pos2>len2) return true;
41         ++cnt;
42     }
43     t=lcp(pos,pos2);//最后判断一下 可能跳三次以后到达s2最后一位 恰巧相等 
44     pos+=t,pos2+=t;
45     return pos2>len2;
46 }
47 int main(){
48     f[0]=1;
49     for(int i=1;i<=N;++i) f[i]=f[i-1]*p;//预处理p的幂 减少计算耗时 
50     scanf("%d",&T);
51     while(T--){
52         scanf("%s",s1+1);
53         scanf("%s",s2+1);
54         len1=strlen(s1+1),len2=strlen(s2+1);
55         if(len1<len2) {//貌似不用解释了??? 
56             puts("0");
57             continue;
58         }
59         init();//hash 预处理 
60         ans=0;
61         for(int i=1;i<=len1-len2+1;++i)//枚举每一位作为起点 
62             if(check(i)) ++ans;
63         printf("%d\n",ans);
64     }
65     return 0;
66 }

 

洛谷P3763 [TJOI2017]DNA

原文:https://www.cnblogs.com/yu-xing/p/10352000.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!