poj3274~改吐了的哈希表

来源:互联网 发布:java小说阅读器源码 编辑:程序博客网 时间:2024/04/29 17:07

改了一晚上才改对,疯了,没法说更多了

/* sum[i][j]代表0到i这个区间内 ,每位数的个数,j代表是第几位。
明显sum[a][j]-sum[b][j]中每个j都是相等时说明这个区间内是“平衡”的
所以可以用c[i][j]代表是否2者区间内是否平衡,c[i][j]=sum[i][j]-sum[i][0];
*/
#include<iostream>#include<string>#include<cmath>#define M 100005using namespace std;int n,k,Max,flag,sum[M][32],c[M][32],vis[M];struct COW{int v;int p;struct COW *next;};struct COW *hash[M];void insert(struct COW *h,int i){int m;if(h->v==0){h->v=1;h->p=i;h->next=new struct COW;h->next->v=0;}else{int f=1;for(int j=0;j<k;j++)  //判断这个hash中是否有平衡区间,即二者的c全部相等的if(c[i][j]!=c[h->p][j]){f=0;break;}m=i-(h->p); //这个就是距离if(f&&m>Max){Max=m;}insert(h->next,i);}} int main(){int i,j,x,m,key;memset(vis,0,sizeof(vis));scanf("%d%d",&n,&k);for(j=0;j<k;j++)    //给0初始化,i是从1开始的{sum[0][j]=0;c[0][j]=0;}vis[0]=1;  //往hash中插入0hash[0]=new struct COW;hash[0]->v=0;hash[0]->next=NULL;insert(hash[0],0);Max=flag=0;for(i=1;i<=n;i++){scanf("%d",&x);for(j=0;j<k;j++){sum[i][j]=(x&1)+sum[i-1][j];  //位运算用在与二进制有关的题目真的非常好用!/* 注意,x&1+1 =x&(1+1)*/x=x>>1;}key=0;for(m=0;m<k;m++){c[i][m]=sum[i][m]-sum[i][0];  //算ckey+=c[i][m]*m; //hash的key值为c值*m的总和}key=abs(key);key=key%M;if(vis[key]==0){vis[key]=1;hash[key]=new struct COW;hash[key]->v=0;hash[key]->next=NULL;}insert(hash[key],i);}printf("%d\n",Max);return 0;}




1 0
原创粉丝点击