D : Hidden Anagrams

题目来源:
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值