hdu-4080 Stammering Aliens 字符串hash 模板题
http://acm.hdu.edu.cn/showproblem.php?pid=4080
求出现次数大于等于n的最长串。
#include<iostream> #include<cstdlib> #include<cstdio> #include<vector> #include <string> #include <map> #define LL long long using namespace std; const LL p=1e9+7; const LL mod=1e9+9;//23333 951413 11111111111111111111111 const LL N=100005; string s; LL n,st; LL has[N];//计算前缀has LL xp[N];//计算p的次方值,用于还原区间hash LL fastMi(LL a,LL b){ LL k,mut=1; if(b==0) return 1; k=a*a; if(b%2!=0) mut*=a; mut*=fastMi(k,b/2); return mut; } int idx(char x) { return x-'a'+1; } void ini_has() { xp[0]=1; for(int i=1;i<N;i++) xp[i]=xp[i-1]*p,xp[i]%=mod; } void m_has(string &s) { has[0]=0; for(int i=1;i<=s.length();i++) has[i]=(has[i-1]*p+idx(s[i-1]))%mod; } LL g_has(int l,int r)//[l+1,r] { return ((has[r]-has[l]*xp[r-l])%mod+mod)%mod; } struct node { int c; int s; node(int cc,int ss) { c=cc; s=ss; } node(){ } }; bool ok(int len) { //cout<<len<<endl; map<int,node> mp; for(int i=0;i+len<=s.length();i++) { LL h=g_has(i,i+len); if(mp.find(h)==mp.end()) mp[h]=node(1,i); else { mp[h].c++; mp[h].s=i; } } bool f=false; st=-1; for(map<int,node>::iterator it=mp.begin();it!=mp.end();it++) { if(it->second.c>=n) { f=true; st=max(st,(LL)it->second.s); } } return f; } int bins(int l,int r) { while(r-l>=3) { int mid=(l+r)/2; if(ok(mid))l=mid; else r=mid-1; } for(int i=r;i>=l;i--) if(ok(i))return i; return 0; } int main() { cin.sync_with_stdio(false); ini_has(); while(cin>>n) { if(!n)break; cin>>s; has[0]=0; m_has(s); int ans=bins(1,s.length()); if(ans) { cout<<ans<<' '<<st<<endl; }else{ cout<<"none"<<endl;} } return 0; }