「UVA1223」 Editor

题意

给一个字符串,求最长的出现了两次以上的子串长度。

分析

二分长度,枚举起点后记录哈希值出现次数即可。

单次复杂度 \(O(n\log n)\)

Code

#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
// static char buf[100],*p1=buf,*p2=buf,obuf[100],*p3=obuf;
// #define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++
// #define putchar(x) (p3-obuf<100)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());
#define dbg(x) cout<<#x<<": "<<x<<"\n"
#define usetime() printf("time: %.3lfs\n",clock()*1.0/CLOCKS_PER_SEC)
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}short top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');}
namespace tobe{
    const ll maxn=5e3+5,mod=998244353;
	ll n;
	ull bas=233,pw[maxn],has[maxn];
	char s[maxn];
	unordered_map<ull,ll>cnt;
	inline ull hash(ll l,ll r){return has[r]-has[l-1]*pw[r-l+1];}
    inline bool chk(ll x){
    	cnt.clear();
    	for(ll i=1;i+x-1<=n;++i){
    		ull now=hash(i,i+x-1);
    		++cnt[now];
    		if(cnt[now]==2)return 1;
    	}return 0;
    }
    inline void mian(){
		scanf("%s",s+1);n=strlen(s+1);
		pw[0]=1;
		for(ll i=1;i<=n;++i)pw[i]=pw[i-1]*bas,has[i]=has[i-1]*bas+s[i];
		ll l=1,r=n,ans=0;
		while(l<=r){
			ll mid=(l+r)>>1;
			if(chk(mid))l=mid+1,ans=mid;
			else r=mid-1;
		}write(ans);
    }
}
signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ll t=read();
    while(t--)tobe::mian();
    // fwrite(obuf,p3-obuf,1,stdout);
    return 0;
}
posted @ 2024-12-20 15:34  run-away  阅读(9)  评论(0)    收藏  举报