zoukankan      html  css  js  c++  java
  • A Secret HDU

    A Secret

     HDU - 6153

     题意:给两个串s1,s2,问s2的所有后缀在s1中出现的次数乘以后缀长度的和是多少。

    首先将串翻转,然后KMP即可。

    通过这个题我也认识到对很多简单的算法理解的不够深刻,学了也就只会耍耍模板,以后要多思考思考。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 const int maxn=1e6+10;
     5 const int mod=1e9+7;
     6 char s[maxn],p[maxn];
     7 int f[maxn];
     8 int lens,lenp;
     9 ll ans;
    10 
    11 void getfail(char* p){
    12     f[0]=f[1]=0;
    13     for(int i=1;i<lenp;i++){
    14         int j=f[i];
    15         while(j&&p[i]!=p[j]) j=f[j];
    16         f[i+1]=p[i]==p[j]?j+1:0;
    17     }
    18     return ;
    19 }
    20 
    21 void KMP(char* s,char* p){
    22     getfail(p);
    23     ll j=0;
    24     for(ll i=0;i<lens;i++){
    25         while(j&&s[i]!=p[j]) {
    26             ans=(ans+(j+1)*j/2)%mod;
    27             j=f[j];
    28         }
    29         if(s[i]==p[j]) j++;
    30         if(j==lenp){
    31             ans=(ans+(j+1)*j/2)%mod;
    32             j=f[j];
    33         }
    34     }
    35     while(j){
    36       ans=(ans+j*(j+1)/2)%mod;
    37       j=f[j];
    38     }
    39     return ;
    40 }
    41 
    42 int main(){
    43     int t;
    44     scanf("%d",&t);
    45     while(t--){
    46         ans=0;
    47         scanf("%s%s",s,p);
    48         lens=strlen(s);
    49         lenp=strlen(p);
    50         reverse(s,s+lens);
    51         reverse(p,p+lenp);
    52         KMP(s,p);
    53         printf("%lld
    ",ans);
    54     }
    55     return 0;
    56 }
    View Code

    上面的代码虽然过了,可是对于这组数据答案是错的=_=

    baabaa

    caabaa

    23

    看到了扩展KMP~去学习下再来补~

    是可以用扩展KMP秒掉的~

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 const int maxn=1e6+10;
     5 const int mod=1e9+7;
     6 
     7 char s[maxn],t[maxn];
     8 int nex[maxn],ex[maxn];
     9 int lens,lent;
    10 void getnex(char* t){
    11     nex[0]=lent;
    12     int a=0,p=0;
    13     for(int i=1;i<lent;i++){
    14         if(i>=p||i+nex[i-a]>=p){
    15             if(i>=p) p=i;
    16             while(p<lent&&t[p]==t[p-i]) p++;
    17             nex[i]=p-i;
    18             a=i;
    19         }else nex[i]=nex[i-a];
    20     }
    21 }
    22 void exkmp(char* s,char* t){
    23     getnex(t);
    24     int a=0,p=0;
    25     for(int i=0;i<lens;i++){
    26         if(i>=p||i+nex[i-a]>=p){
    27             if(i>=p) p=i;
    28             while(p<lens&&p-i<lent&&s[p]==t[p-i]) p++;
    29             ex[i]=p-i;
    30             a=i;
    31         }else ex[i]=nex[i-a];
    32     }
    33 }
    34 int main(){
    35     int T;
    36     scanf("%d",&T);
    37     while(T--){
    38         scanf("%s%s",s,t);
    39         lens=strlen(s);
    40         lent=strlen(t);
    41         reverse(s,s+lens);
    42         reverse(t,t+lent);
    43         exkmp(s,t);
    44         ll ans=0;
    45         for(int i=0;i<lens;i++) if(ex[i]) ans=(ans+1ll*(ex[i]+1)*ex[i]/2)%mod;
    46         printf("%lld
    ",ans);
    47     }
    48 }
    View Code
  • 相关阅读:
    【python】 time模块和datetime模块详解 【转】
    【python 】装饰器 (多个参数的函数,带参数的装饰器)【转】
    从测试角度对测试驱动开发的思考【转】
    mysql性能优化-慢查询分析、优化索引和配置【转】
    【python 】Requests 库学习笔记
    二本院校计算机专业考研上岸985
    mysql创建触发器
    pat 1134 Vertex Cover (25分) 超时问题
    数据库三级封锁协议简述
    pat 1139 First Contact (30分) 题目详解
  • 原文地址:https://www.cnblogs.com/yijiull/p/7405757.html
Copyright © 2011-2022 走看看