HDU4821(2013 Asia Regional Changchun - I)
2016-09-08 12:07
176 查看
Problem : String
Description :
给你一个字符串S,让你求出符合条件的子串的数量: 子串的长度是M∗L,同时这个子串分成M个长度为L的小子串后两两不相同。
Solution :
字符串hash算法(BKDRHash)+暴力美学。字符串的这个hash算法我是看别人的,我是真的不知道还有这么个东西,我自己想的hash与之类似,不过我的权数是26,而它的权数是31。暴力部分就是我的作品了,暴力美学。对于每个子串的hash值只能用用公式计算,而不能模拟!而子串又是一个区间问题,那么就可以先预处理出1→i的哈希值,然后用公式hashvalue[e]−hashvalue[s]∗POWER[e−s]计算出来就好了。之后就是对M个小子串进行比较了,这里我们用map来比较,如果把M个小子串的哈希值放进去后发现map的容量为M,那么就满足条件了。对于后续的小子串处理,我们把之前的M个子串中的第一个位置除去,再加上接下来的一个子串。这样就构成了一个新的子串,我们判断这个新的map容量是不是符合条件就可以了,如何做到这个呢,我用了一个队列来动态保存这M个子串。最后一点,我们为了避免重复,可以利用希尔排序的分组的思想,把S分成L个组,这样分出来判断就绝对不会重复了。
Code(C++) :
Description :
给你一个字符串S,让你求出符合条件的子串的数量: 子串的长度是M∗L,同时这个子串分成M个长度为L的小子串后两两不相同。
Solution :
字符串hash算法(BKDRHash)+暴力美学。字符串的这个hash算法我是看别人的,我是真的不知道还有这么个东西,我自己想的hash与之类似,不过我的权数是26,而它的权数是31。暴力部分就是我的作品了,暴力美学。对于每个子串的hash值只能用用公式计算,而不能模拟!而子串又是一个区间问题,那么就可以先预处理出1→i的哈希值,然后用公式hashvalue[e]−hashvalue[s]∗POWER[e−s]计算出来就好了。之后就是对M个小子串进行比较了,这里我们用map来比较,如果把M个小子串的哈希值放进去后发现map的容量为M,那么就满足条件了。对于后续的小子串处理,我们把之前的M个子串中的第一个位置除去,再加上接下来的一个子串。这样就构成了一个新的子串,我们判断这个新的map容量是不是符合条件就可以了,如何做到这个呢,我用了一个队列来动态保存这M个子串。最后一点,我们为了避免重复,可以利用希尔排序的分组的思想,把S分成L个组,这样分出来判断就绝对不会重复了。
Code(C++) :
#include <stdio.h> #include <string.h> #include <map> #include <queue> using namespace std; typedef unsigned long long ULL; const int MAXN=100000+5; const int base=31; char str[MAXN]; int M,L; int len; ULL hash_value[MAXN]; ULL POWER[MAXN]; void init() { POWER[0]=1; for(int i=1;i<MAXN;i++) POWER[i]=POWER[i-1]*base; } ULL get_hash(int s,int e) { if(s<0) return hash_value[e]; return hash_value[e]-hash_value[s]*POWER[e-s]; } int main() { //freopen("in","r",stdin); init(); while(~scanf("%d%d",&M,&L)){ scanf("%s",str); len=strlen(str); for(int i=0;i<MAXN;i++) hash_value[i]=0; hash_value[0]=str[0]-'a'+1; for(int i=1;i<len;i++) hash_value[i]=(hash_value[i-1]*base+str[i]-'a'+1); map<ULL,int> m; queue<ULL> que; int ans=0; for(int i=0;i<L&&i+M*L<=len;i++){ m.clear(); while(!que.empty()) que.pop(); for(int j=i;j+L<=i+M*L;j+=L){ ULL tmp=get_hash(j-1,j+L-1); ++m[tmp]; que.push(tmp); } if(m.size()==M) ++ans; for(int j=i+M*L;j+L<=len;j+=L){ ULL head=que.front(); que.pop(); --m[head]; if(m[head]==0) m.erase(head); ULL tail=get_hash(j-1,j+L-1); ++m[tail]; que.push(tail); if(m.size()==M) ++ans; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu 4762 Cut the Cake 概率(2013 ACM/ICPC Asia Regional Changchun Online 1004)
- 2012 Asia ChangChun Regional Contest(2013区域赛练习)
- HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)
- HDU-4819 Mosaic (二维线段树)(2013 Asia Regional Changchun)
- 2013 Asia Regional Changchun I 题,HDU(4821),Hash
- 2013 Asia Regional Changchun HDU - 4814 Golden Radio Base (进制模拟)
- 2013 Asia Regional Changchun 解题报告
- 2013 ACM/ICPC Asia Regional Changchun Online (2013网络赛)
- 2013 Asia Regional Changchun HDU 4821 String (BKDRhash+成段移动法判字符串)
- 2013 ACM/ICPC Asia Regional Changchun Online Problem J & hdu4768 Flyer(二分)
- 2013 Asia Regional Changchun
- 2013 ACM/ICPC Asia Regional Changchun Online
- 2013 Asia Regional Changchun
- 2013 ACM/ICPC Asia Regional Changchun Online
- 2013 Asia Regional Changchun HDU 4819 Mosaic (二维线段树)
- hdu4759 Poker Shuffle 2013 ACM/ICPC Asia Regional Changchun Online
- 2013 Asia Regional Changchun C
- 2013 ACM/ICPC Asia Regional Changchun Online----hdu4762 Cut the Cake
- 2013 Asia Regional Changchun HDU 4816 Bathysphere(数学)
- hdu 4768 Flyer 二分(2013 ACM/ICPC Asia Regional Changchun Online 1010)