现在的位置: 主页 > 公司荣誉 > 文章列表

字符串hash,bzoj2795[Poi2012]A Horrible Poem

作者:成都金海力科技有限公司 来源:www.scjinhaili.com 未知发布时间:2017-09-02 11:48:44
字符串hash,bzoj2795[Poi2012]A Horrible Poem unsigned int BKDRHash(char *str) { unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); }

将每一个字符串设成一个数。

我们也可以用hash来判断两个子串是否相等。

#include #include #define seed 131 char s[10]; long long hash[10]; long long bit[10]; long long calc(int l,int r) { return hash[r]-hash[l-1]*bit[r-l+1]; } int main() { scanf(%s,s); int n=strlen(s); for(int i=0;i 让我们来模拟一下:

样例:abab

hash[ 1 ] = a;

hash[ 2 ] = a*seed+b;

hash[ 3 ] = a*seed^2+b*seed+a;

hash[ 4 ] = a*seed^3+b*seed^2+a*seed+b;

bit[1]=seed, bit[2]=seed^2,bit[3]=seed^3,bit[4]=seed^4;

cal(1, 2)=a*seed+b;

cal(3, 4)=hash[ 4 ]-hash[2]*bit[2]=a*seed+b;

^-^更快^-^

……………………………………………………………………………………………………………………………………………………………………………………………………………

bzoj2795

[Poi2012]A Horrible Poem 1、若循环节长度为len ,则[st,to-len]与[st+len,to]相同; 2、len是字符串总长度的约数; 所以枚举字符串长度的质因数k,将这个字符串分成k份,判断把每一份当做循环节是否成立。 把找到的循环节再不断分解,直到不能再分为止。#include #include #include #include #define seed 131 using namespace std; typedef unsigned long long ll; ll l; char s[500100]; ll q; ll len,st,to; vector >pri[500100]; bool vis[500100]; void init()//预处理每个 长度 的质因数及其个数,放在pri里。 { for(ll i=2;i<=l;i++) { if(!vis[i]) { for(ll j=i;j<=l;j+=i) { ll h=0; ll v=j; while(v%i==0) { v/=i; h++; } pri[j].push_back(make_pair(i,h)); vis[j]=true; } } } } ll hash[500100]; ll bit[500100]; ll cal(ll f,ll t) { return hash[t]-hash[f-1]*bit[t-f+1]; } int main() { // freopen(str.in,r,stdin); // freopen(str.out,w,stdout); scanf(%llu,&l); scanf(%s,s+1); for(ll i=1;i<=l;i++)//字符串hash { hash[i]=hash[i-1]*seed+s[i]; } bit[0]=1; for(ll i=1;i<=l;i++) { bit[i]=bit[i-1]*seed; } init(); scanf(%llu,&q); while(q--) { scanf(%llu %llu,&st,&to); len=to-st+1; ll ans=len; for(int i=0;i<(int)pri[len].size();i++) { ll k=pri[len][i].first; ll p=pri[len][i].second; ll mul=1; for(ll j=1;j<=p;j++) { mul*=k; } while(p--) { ll xun=len/mul; if(cal(st,to-xun)==cal(st+xun,to)) { ans/=mul; break; } mul/=k; } } printf(%llu ,ans); } }

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:鄂州SEO http://ezhou.4567w.com

上一篇:黄冈网站制作公司哪家好?首选肥猫科技027-82823488 下一篇:最后一页