题目来源:
CSUOJ 2294: Hidden Anagrams
Gym101158D-Hidden Anagrams
2016-2017 ACM-ICPC, Asia Tsukuba Regional Contest D Hidden Anagrams
哈希hash
因为与字母顺序无关,可以令每一个字母等于一个数值
字符串的哈希值为字母对应数值之和
滚动哈希优化效率
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#include <sstream>
#define LL long long
#define LD long double
#define ULL unsigned long long
#define UI unsigned int
#define _for(i,j,k) for(int i=j;i<=k;i++)
#define for_(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) (x&-x)
#define ls(x) x<<1
#define rs(x) x<<1|1
//#pragma comment(linker, "/STACK:10240000000,10240000000")
using namespace std;
const int maxn = 4e3+3;
const int hz = maxn*maxn;
int head[1000*maxn],net[hz],hs[hz],cnt;
string a,b;
int tk[26],ta[maxn][maxn],tb[maxn];
int isp[150],p[50];
void hinsert(int h,int fr,int ft){
hs[++cnt]=fr*maxn+ft;
net[cnt]=head[h];
head[h]=cnt;
}
void init(){
_for(i,2,15){
if(!isp[i]) for(int j=i*i;j<150;j+=i) isp[j]=1;
}
_for(i,2,149) if(!isp[i]) p[++p[0]]=i;
_for(i,0,25){
//tk[i] = p[i+1]+67;
tk[i] = (i+2)*(i+3)+p[i+1];
}
int la=a.length(),lb=b.length();
ta[0][0]=tk[a[0]-'a'];
_for(i,1,la-1){
ta[0][i]=ta[0][i-1]+tk[a[i]-'a'];
}
_for(i,1,la-1){
_for(j,i,la-1){
ta[i][j]=ta[0][j]-ta[0][i-1];
}
}
tb[0]=tk[b[0]-'a'];
hinsert(tb[0],0,0);
_for(i,1,lb-1){
tb[i]=tb[i-1]+tk[b[i]-'a'];
hinsert(tb[i],0,i);
}
_for(i,1,lb-1){
_for(j,i,lb-1){
hinsert(tb[j]-tb[i-1],i,j);
}
}
}
bool cp(string& sa,string& sb){
//cout<<sa<<" "<<sb<<endl;
int ca[26],la=sa.length();
_for(i,0,25) ca[i]=0;
_for(i,0,la-1) ca[sa[i]-'a']++;
_for(i,0,la-1) ca[sb[i]-'a']--;
_for(i,0,25) if(ca[i]) return false;
return true;
}
bool hfind(int fr,int ft){
int hk=ta[fr][ft],len=ft-fr+1;
for(int i=head[hk];i;i=net[i]){
int l=hs[i]/maxn,r=hs[i]%maxn;
if(r-l+1==len){
string sa=a.substr(fr,len);
string sb=b.substr(l,len);
if(cp(sa,sb)) return true;
}
}
return false;
}
int solve(){
int la=a.length(),lb=b.length();
int len = min(la,lb);
for_(l,len,1){
_for(i,l-1,la-1){
if(hfind(i-l+1,i)) return l;
}
}
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>a>>b;
init();
cout<<solve();
return 0;
}