POJ 3274 Gold Balanced Lineup

Gold Balanced Lineup
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 10516   Accepted: 3145

Description

Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to narrow down the list of features shared by his cows to a list of only Kdifferent features (1 ≤ K ≤ 30). For example, cows exhibiting feature #1 might have spots, cows exhibiting feature #2 might prefer C to Pascal, and so on.

FJ has even devised a concise way to describe each cow in terms of its "feature ID", a single K-bit integer whose binary representation tells us the set of features exhibited by the cow. As an example, suppose a cow has feature ID = 13. Since 13 written in binary is 1101, this means our cow exhibits features 1, 3, and 4 (reading right to left), but not feature 2. More generally, we find a 1 in the 2^(i-1) place if a cow exhibits feature i.

Always the sensitive fellow, FJ lined up cows 1..N in a long row and noticed that certain ranges of cows are somewhat "balanced" in terms of the features the exhibit. A contiguous range of cows i..j is balanced if each of the K possible features is exhibited by the same number of cows in the range. FJ is curious as to the size of the largest balanced range of cows. See if you can determine it.

Input

Line 1: Two space-separated integers, N and K.  Lines 2..N+1: Line i+1 contains a single K-bit integer specifying the features present in cow i. The least-significant bit of this integer is 1 if the cow exhibits feature #1, and the most-significant bit is 1 if the cow exhibits feature #K.

Output

Line 1: A single integer giving the size of the largest contiguous balanced group of cows.

Sample Input

7 3
7
6
7
2
1
4
2

Sample Output

4

Hint

In the range from cow #3 to cow #6 (of size 4), each feature appears in exactly 2 cows in this range
 
前几天自学哈希时,在别人博客里几乎原模原样地copy了这个题。
话说前面对问题的转化确实很厉害
首先用一个数组sum[i][j]记录从第1到第i头cow属性j的出现次数。
所以题目要求等价为:求满足sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]=.....=sum[i][k-1]-sum[j][k-1] (j<i)中最大的i-j 
将上式变换可得到
  sum[i][1]-sum[i][0] = sum[j][1]-sum[j][0]
  sum[i][2]-sum[i][0] = sum[j][2]-sum[j][0]
  ......
  sum[i][k-1]-sum[i][0] = sum[j][k-1]-sum[j][0] 
令C[i][y]=sum[i][y]-sum[i][0] (0<y<k)
初始条件C[0][0~k-1]=0 (这个初始条件很重要,后面会分析到)
所以只需求满足C[i][]==C[j][] 中最大的i-j,其中0<=j<i<=n。C[i][]==C[j][] 即二维数组C[][]第i行与第j行对应列的值相等。
那么原题就转化为求C数组中 相等且相隔最远的两行的距离i-j
 
但是最大数据有10W个,即10W行,因此不能直接枚举找最大距离,必须用Hash查找相同行,找到相同行再比较最大距离。
注意C数组的值可能为负数,因此生成key值时要注意保证key为非负数。
 
为什么初始条件很重要呢,因为可能会出现下面这种情况
  C[i][0]==C[i][1]==C[i][2]==……==C[i][k]==0
等价于:
  sum[i][0]==sum[i][1]==sum[i][2]==……==sum[i][k]
这意味着从第一行到第i行时,所有feature出现的次数是相同的
可是只要第一次出现C数组全0行即可,而不像其他情况一样需要有两行相同的。
因此这里的做法是将C[0][] 初始化为一个全0行(也就是代码中的Hash(0)),这样出现全0行也就是这一行与C[0][]行相等。这样将这种情况的判定方式也转化成和其他情况一样的了。
 
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 
  6 using namespace std;
  7 
  8 const long mod=99991;
  9 
 10 typedef class node
 11 {
 12     public:
 13         long pi;
 14         class node *next;
 15         node()
 16         {
 17             next=NULL;
 18         }
 19 } HashTable;
 20 
 21 HashTable *cow[mod];
 22 
 23 int feature[100001][30];
 24 int sum[100001][30];
 25 int c[100001][30];
 26 int k;
 27 long n,maxlen;
 28 
 29 bool cmp(long ai,long bi)
 30 {
 31     for(int j=0;j<k;j++)
 32         if(c[ai][j]!=c[bi][j])
 33             return false;
 34     return true;
 35 }
 36 
 37 void Hash(long ci)
 38 {
 39     long key=0;
 40     for(int j=1;j<k;j++)
 41         key+=c[ci][j]*j;
 42     key=((long)fabs((double)key))%mod;
 43     if(!cow[key])
 44     {
 45         HashTable *temp=new HashTable;
 46         temp->pi=ci;
 47         cow[key]=temp;
 48     }
 49     else
 50     {
 51         if(cmp(cow[key]->pi,ci))
 52         {
 53             long dist=ci-(cow[key]->pi);
 54             if(dist>maxlen)
 55                 maxlen=dist;
 56             return;
 57         }
 58         else
 59         {
 60             HashTable *p=cow[key];
 61             while(p->next)
 62             {
 63                 if(cmp(p->next->pi,ci))
 64                 {
 65                     long dist=ci-(p->next->pi);
 66                     if(dist>maxlen)
 67                         maxlen=dist;
 68                     return;
 69                 }
 70                 p=p->next;
 71             }
 72             HashTable *temp=new HashTable;
 73             temp->pi=ci;
 74             p->next=temp;
 75         }
 76     }
 77 }
 78 
 79 int main()
 80 {
 81     long temp;
 82 
 83     while(scanf("%ld %d",&n,&k)==2)
 84     {
 85         for(int i=0;i<k;i++)
 86         {
 87             c[0][i]=0;
 88             sum[0][i]=0;
 89         }
 90         memset(cow,0,sizeof(cow));
 91         Hash(0);
 92         maxlen=0;
 93 
 94         for(int i=1;i<=n;i++)
 95         {
 96             scanf("%ld",&temp);
 97             for(int j=0;j<k;j++)
 98             {
 99                 feature[i][j]=temp&1;
100                 temp>>=1;
101                 sum[i][j]=sum[i-1][j]+feature[i][j];
102                 c[i][j]=sum[i][j]-sum[i][0];
103             }
104             Hash(i);
105         }
106 
107         printf("%ld\n",maxlen);
108     }
109 
110     return 0;
111 }
[C++]

 

posted @ 2013-07-12 20:40  ~~Snail~~  阅读(189)  评论(0编辑  收藏  举报