您的位置:首页 > 其它

POJ3261-哈希

2015-08-20 15:21 337 查看
这个题让求至少出现K次的最大长度的子串,属于最大化最小值问题,首先应该想到二分求字串的长度,二分的过程是O(logN)的,注意judge的时候怎样判断是否满足情况以及满足情况后l,r的变化。可以给每一个子串定一个hash值,判断所有hash值中相同的是否超过K个,hash方法同BDKshash。。POJ数据略水。。a[i]的值远远没有到100W。。poj的字符串题一直感觉数据都不太好。。红着脸水过。。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 20010;
typedef long long ll;

int n,k,seed = 131;
ll base[maxn];
ll one[maxn],hash[maxn];
int a[maxn];

bool judge(int x)
{

for(int i = 1; i <= n-x+1; ++i)
{
hash[i] = one[i+x-1]-one[i-1]*base[x];
}
int j = n-x+1;
sort(hash+1,hash+1+j);
int sum = 1;
for(int i = 1; i <= n-x+1; ++i)
{
if(hash[i] == hash[i+1]) sum++;
else{
if(sum >= k) return true;
else sum = 1;
}
}
if(sum >= k) return true;
else return false;
}

int main()
{
scanf("%d%d",&n,&k);
base[0] = 1;
for(int i = 1; i <= n; ++i) base[i] = base[i-1]*seed;
for(int i = 1; i <= n; ++i)
scanf("%d",a+i);
one[0] = 0;
for(int i = 1; i <= n; i++)
one[i] = one[i-1]*seed+a[i];
int l = 1,r = n,mid,ans;
while(l <= r)
{
int mid = l +(r-l)/2;
if(judge(mid)) l = mid+1,ans = mid;
else r = mid-1;
}
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: