「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; }
本文作者:run-away
本文链接:https://www.cnblogs.com/run-away/p/18619409
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步