poj 3274

#include<iostream>
#include<fstream>
using namespace std;
#define N 100003
int n,k,tmp,mask,sum,jump,res;
int arr[100005][35];
int h[N];
bool same;
int main(){
		//streambuf *backup;   
  //  ifstream fin;   
  //  fin.open("data.in");   
  //  backup = cin.rdbuf();   // back up cin's streambuf   
  //  cin.rdbuf(fin.rdbuf()); // assign file's streambuf to cin
	cin>>n>>k;
	memset(arr,0,sizeof(arr));
	memset(h,-1,sizeof(h));
	for(int i=1;i<=n;i++){
		cin>>tmp;
		mask=1;
		for(int j=0;j<k;j++){
			if(tmp&mask){
				arr[i][j]=arr[i-1][j]+1;
			}else{
				arr[i][j]=arr[i-1][j];
			}
			mask=(mask<<1);
		}
	}
	for(int i=1;i<=n;i++){
		tmp = arr[i][0];
		for(int j=0;j<k;j++){
			arr[i][j]=arr[i][j]-tmp;
		}
	}
	res=0;
	for(int i=0;i<=n;i++){
		sum=0;
		for(int j=1;j<k;j++){
			sum+=(arr[i][j]*j);
		}
		if(sum<0)
			sum=-sum;
		sum=sum%N;
		jump=1;		
		same=false;
		while(h[sum]!=-1){
			same=true;
			for(int j=1;j<k;j++){
				if(arr[h[sum]][j]!=arr[i][j]){
					same=false;
					break;
				}
			}
			if(same){
				if(i-h[sum]>res){
					res=i-h[sum];					
				}
				break;
			}else{
				sum=sum+jump*jump;
				sum=sum%N;
				jump++;
			}
		}
		if(!same){
			h[sum]=i;
		}
	}
	cout<<res<<endl;
	return 0;
}

可以转化为数列相等问题

几个版本的hash

int hash(int x)
{
  int sum=0;
  for(int i=2;i<=k;++i){
	sum*=ha;
	sum+=a[x][i];
	sum%=hm;
	if(sum<0)sum+=hm;
  }
  return sum;
}

//hm=100003,ha=41

折叠法
inline int hashcode(const int *v)
{
	int s = 0;
	for(int i=0; i<k; i++)
		s=((s<<2)+(v[i]>>4))^(v[i]<<10);
	s = s % M;
	s = s < 0 ? s + M : s;
	return s;
}

UNIX下的字符串哈希函数
int ELFhash(char *key) /// 此乃UNIX系统使用的哈希,绝对有价值
{
    unsigned long h = 0;
    while (*key){
        h = (h << 4) + *key++;
        unsigned long g = h & 0xf0000000L; // 1个f,7个0
        if (g) h ^= g >> 24;
        h &= ~g;
    }
    return (h+M) % M; // M is Prime
}

int hashcode(const L&a) /// 把数字的转换为字符串,进行哈希,以后就不用费心思设计哈希了
{
    char str[32*8];
    char *s = (char*)(&a.d[1]);
    int i;
    for (i = 0; i < k-1; i++){
        str[i] = 'a' + s[i];
    }
    str[i] = 0;
    return ELFhash(str);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值