「UVA11107」 Life Forms

题意

\(n\) 个字符串,求最长的在超过 \(\lfloor\frac{n}{2}\rfloor\) 个串里出现的子串,若有多个按字典序排序后输出;若不存在输出 ?

分析

不理解这么水的题为什么要用后缀数组。

预处理每个串的 Hash 值,二分子串长度,变成判定存不存在的问题。

枚举每个串的子串起始位置,用 unordered_map 记录 Hash 值,若出现次数达到要求那这就是一个答案。

复杂度 \(O(n|s|\log|s|)\)

注意这个题要求在每个测试点中间输出一个空行,而且结尾不能有空格和换行。

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=1e2+5,maxm=1e3+5,mod=998244353;
	ll n,mn,m[maxn];
	ull bas=233,pw[maxm],has[maxn][maxm];
	string s[maxn];
	inline ull hash(ll id,ll l,ll r){
		return has[id][r]-has[id][l-1]*pw[r-l+1];
	}
	unordered_map<ull,ll>cnt,vis;
	vector<string>out;
	inline bool chk(ll x){
		cnt.clear();
		for(ll i=1;i<=n;++i){
			vis.clear();
			for(ll j=1;j+x-1<=m[i];++j){
				ll now=hash(i,j,j+x-1);
				if(!vis[now])++cnt[now],vis[now]=1;
				if(cnt[now]>=n/2+1)return 1;
			}
		}return 0;
	}
    inline void mian(){
    	ll tmp=0;
    	pw[0]=1;
    	for(ll i=1;i<maxm;++i)pw[i]=pw[i-1]*bas;
    	while(n=read()){
    		mn=INT_MAX;
			if(!n)exit(0);
			if(tmp)puts("");
			++tmp;
			for(ll i=1;i<=n;++i){
				cin>>s[i],m[i]=s[i].size(),s[i]=" "+s[i];
				mn=min(mn,m[i]);
				for(ll j=1;j<=m[i];++j)has[i][j]=has[i][j-1]*bas+s[i][j];
			}
			ll l=0,r=mn,ans=0;
			while(l<=r){
				ll mid=(l+r)>>1;
				if(chk(mid))l=mid+1,ans=mid;
				else r=mid-1;
			}
			if(!ans){puts("?");continue;}
			cnt.clear(),vis.clear(),out.clear();
			for(ll i=1;i<=n;++i){
				vis.clear();
				for(ll j=1;j+ans-1<=m[i];++j){
					ll now=hash(i,j,j+ans-1);
					if(!vis[now])++cnt[now],vis[now]=1;
					if(cnt[now]>=n/2+1)out.push_back(s[i].substr(j,ans));
				}
			}
			sort(out.begin(),out.end());
			out.erase(unique(out.begin(),out.end()),out.end());
			for(auto v:out)cout<<v<<'\n';
    	}
    }
}
signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ll t=1;
    while(t--)tobe::mian();
    // fwrite(obuf,p3-obuf,1,stdout);
    return 0;
}
posted @ 2024-12-20 15:33  run-away  阅读(11)  评论(0)    收藏  举报