poj3274数位HASH

来源:互联网 发布:cpu卡发卡软件 编辑:程序博客网 时间:2024/05/01 10:32
//题意:求解最大的连续区间使得该区间中每种特征出现的次数是相等的//可以用树状数组类似方法求解sum[i][]表示0-i所有属性出现的次数//那么就是求sum[j][] - sum[i][]最大的j-i的值//sum[j][k]-sum[i][k] = sum[j][0]- sum[i][0]  sum[j][k] - sum[j][0] = sun[i][k] - sum[i][0]#include <iostream>#include <stdio.h>#include <string.h>using namespace std;#define  MAXN  100010static int n;static int nsum[MAXN][31];static int C[MAXN][31];static int K;static const int mod=99991;static int maxans;typedef struct HashNode{int data[31];int num;HashNode* next;HashNode(){next = 0;}}*HashTable;HashTable xHash[mod];static int getHash(int num){int key = 0;//与位置有关的话for (int i=0;i<K;++i){key+= C[num][i]*i;}key>0?key:key = -key;key%=mod;return key;}static void initHash(){memset(xHash,0,sizeof(xHash));}static bool kmpd(HashTable a,int*d){for (int i=0;i<K;++i){if (a->data[i]!=d[i]) return false;}return true;}static void insertHash(int num){int key = getHash(num);if (xHash[key]==0){xHash[key] = new HashNode();for (int i=0;i<K;++i) xHash[key]->data[i] = C[num][i];xHash[key]->next = 0;xHash[key]->num = num;return;}else{HashTable head = xHash[key];for (head;head!=0;head = head->next){if (kmpd(head,C[num])){    int dif = num - head->num;if (dif>maxans) maxans = dif;return;}}head = xHash[key];HashTable tmp = new HashNode();for (int i=0;i<K;++i)tmp->data[i] = C[num][i];tmp->num = num;tmp->next = head;xHash[key] = tmp;}}static int xpow(int a,int s){if (s==0) return 1;int t = xpow(a*a,s/2);if (s&1) t*=a;return t;}int main(){scanf("%d %d",&n,&K);int p;memset(nsum,0,sizeof(nsum));memset(C,0,sizeof(C));for (int i=1;i<=n;++i){scanf("%d",&p);if (p==xpow(2,K)-1) maxans = 1;for (int j=0;j<K;++j){if (i==0){if ((1<<j)&p)nsum[i][j]++;}else{nsum[i][j] = nsum[i-1][j];if ((1<<j)&p)nsum[i][j]++;}C[i][j] = nsum[i][j];}for (int j=0;j<K;++j)    C[i][j]-=nsum[i][0];}initHash();insertHash(0);for (int i=1;i<=n;++i)insertHash(i);printf("%d\n",maxans);return 0;}

0 0