首页 > 代码库 > POJ 1743 Musical Theme Hash+二分
POJ 1743 Musical Theme Hash+二分
题目大意:有一段优美的旋律,他们是由一些不超过88的音调组成的。若把五个音调算作一小节,问是否有超过一小节的韵律相同(差相同,且两个相同的韵律之间不能有重叠),并求这个最长的长度。
思路:这个题是男人八题之一,正解是后缀自动机,可是我不会。但是某神犇说过:“Hash大法好”。于是这个题Hash+二分也可以解决。分析时间复杂度,2w个点,二分logn,hash挂链判断O(kn),总复杂度O(knlogn),解决。
将原数组两两做差,然后按照这个数组hash。二分枚举最长的相同的韵律长度,枚举每一个开始的时间,然后判断两个韵律是否重叠,这个都放在hash表里就行了。
思路:这个题是男人八题之一,正解是后缀自动机,可是我不会。但是某神犇说过:“Hash大法好”。于是这个题Hash+二分也可以解决。分析时间复杂度,2w个点,二分logn,hash挂链判断O(kn),总复杂度O(knlogn),解决。
将原数组两两做差,然后按照这个数组hash。二分枚举最长的相同的韵律长度,枚举每一个开始的时间,然后判断两个韵律是否重叠,这个都放在hash表里就行了。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define BASE 177 #define MAX 20010 using namespace std; struct HashSet{ static const int mo = 9997; int head[mo + 100],total; int next[MAX],pos[MAX]; unsigned long long true_hash[MAX]; void Clear() { memset(head,0,sizeof(head)); total = 0; } bool Insert(unsigned long long hash,int _pos,int ans) { int x = hash % mo; for(int i = head[x];i;i = next[i]) if(true_hash[i] == hash && _pos - pos[i] > ans) return true; next[++total] = head[x]; true_hash[total] = hash; pos[total] = _pos; head[x] = total; return false; } }map; unsigned long long p[MAX]; unsigned long long hash[MAX]; int cnt; int _src[MAX],src[MAX]; void Pretreatment(); inline bool Judge(int ans); int main() { Pretreatment(); while(scanf("%d",&cnt),cnt) { for(int i = 1;i <= cnt; ++i) scanf("%d",&_src[i]); for(int i = 1;i < cnt; ++i) src[i] = _src[i + 1] - _src[i] + 88; hash[0] = 0; for(int i = 1;i < cnt; ++i) hash[i] = hash[i - 1] * BASE + src[i]; int l = 0,r = cnt,ans = 0; while(l <= r) { int mid = (l + r) >> 1; if(Judge(mid)) l = mid + 1,ans = mid; else r = mid - 1; } ans++; if(ans < 5) ans = 0; printf("%d\n",ans); } return 0; } void Pretreatment() { p[0] = 1; for(int i = 1;i < MAX; ++i) p[i] = p[i - 1] * BASE; } inline bool Judge(int ans) { map.Clear(); for(int i = ans;i < cnt; ++i) if(map.Insert((unsigned long long)hash[i] - hash[i - ans] * p[ans],i,ans)) return true; return false; }
POJ 1743 Musical Theme Hash+二分
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。