湖南师范大学2018年大学生程序设计竞赛新生赛 D小Y的字符串

#include <bits/stdc++.h>
#define mp make_pair
#define pi pair<int,int>
#define ll long long
using namespace std;
const int m1=666623333;
const int m2=1004535809;
char a[200005],b[200005];
int h1[200005],h2[200005],n,m;
int g1[200005],g2[200005];
int p1[200005],p2[200005];
ll ans=0;
inline pi get1(int l,int r)
{int o1=h1[r]-1ll*h1[l-1]*p1[r-l+1]%m1;
int o2=h2[r]-1ll*h2[l-1]*p2[r-l+1]%m2;
o1=(o1<0?o1+m1:o1);
o2=(o2<0?o2+m2:o2);
return mp(o1,o2);
}
inline pi get2(int l,int r)
{int o1=g1[r]-1ll*g1[l-1]*p1[r-l+1]%m1;
int o2=g2[r]-1ll*g2[l-1]*p2[r-l+1]%m2;
o1=(o1<0?o1+m1:o1);
o2=(o2<0?o2+m2:o2);
return mp(o1,o2);
}
int main (){
    int i,j;
    scanf ("%s",a+1);
    scanf ("%s",b+1);
    n=strlen(a+1);
    m=strlen(b+1);
    a[n+1]='0';
    b[m+1]='0';
    p1[0]=p2[0]=1;
    for (i=1;i<=n;i++)
    {p1[i]=37ll*p1[i-1]%m1;
    p2[i]=93ll*p2[i-1]%m2;
    }
    for (i=1;i<=n;i++)
    {h1[i]=(37ll*h1[i-1]+a[i]-'a'+1)%m1;
    h2[i]=(93ll*h2[i-1]+a[i]-'a'+1)%m2;
    }
    for (i=1;i<=m;i++)
    {g1[i]=(37ll*g1[i-1]+b[i]-'a'+1)%m1;
    g2[i]=(93ll*g2[i-1]+b[i]-'a'+1)%m2;
    }
    for (i=1;i<=n;i++)
    {int l=1,r=min(n-i+1,m);
    while (l<=r)
    {int mid=(l+r)>>1;
    if (get1(i,i+mid-1)==get2(1,mid)) {l=mid+1;}
    else {r=mid-1;}
    }
    if (r==m) {ans+=(m-1);continue;}
    if (a[i+r]>b[r+1]) {ans+=r;continue;}
    ans+=(n-i+1);
    }
    printf ("%lld\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值