别样的hash大战
  • 板块P10476 Necklace
  • 楼主LL_xdfz
  • 当前回复4
  • 已保存回复4
  • 发布时间2025/7/23 20:03
  • 上次更新2025/7/24 09:49:03
查看原帖
别样的hash大战
1629093
LL_xdfz楼主2025/7/23 20:03

这题是看到双指针进来的,然后发现可以直接 hash 。

然后就水过了,以下是我的代码:

#include<bits/stdc++.h>
using namespace std;
char a[2000010],b[1000010];
int n;
const long long p=13331;
unsigned long long h[2000010],h1[1000010],g[2000010];
void init(){
    g[0]=1;
    for(int i=1;i<=n;i++)g[i]=g[i-1]*p;
    for(int i=1;i<=n;i++){
        h[i]=h[i-1]*p+a[i];
        if(i<=n/2)h1[i]=h1[i-1]*p+b[i];
    }
}
unsigned long long has(int l,int r){
    return h[r]-h[l-1]*g[r-l+1];
}
int ans;
bool check(int s1,int s2){
    int l=1,r=n,len=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(has(s1,s1+mid-1)==has(s2,s2+mid-1))l=mid+1,len=mid;
        else r=mid-1;
    }
    if(len==n)return 0;
    else return a[s1+len]>a[s2+len];
}
int main(){
    scanf("%s",a+1);
    scanf("%s",b+1);
    n=strlen(a+1);
    for(int i=1;i<=n;i++)a[i+n]=a[i];
    n*=2;
    init();
    int ff=0;
    for(int i=1;i<=n/2;i++){
        if(has(i,i+n/2-1)==h1[n/2]){
            cout<<"Yes\n";
            ff=1;
            break;
        }
    }
    if(ff!=1)return cout<<"No\n",0;
    for(int i=1;i<=n/2;i++){
        if(!ans)ans=i;
        else if(check(ans,i))ans=i;
    }
    for(int i=ans;i<=ans+n/2-1;i++)cout<<a[i];
    return 0;
}

本质上就是把串复制一遍,用二分判断字典序

所以可不可以再标签上加 hash 呢?

2025/7/23 20:03
加载中...