POJ 3274 Gold Balance Lineup

来源:互联网 发布:mac默认图片查看器 编辑:程序博客网 时间:2024/06/16 11:56

抽象一下,此题给你10W个数,让你求一个[i,j],使得a[i]到a[j]的数的二进制每一位上的1出现的次数相等,并使j-i+1最大。
解法:
      我们把每个数化为二进制把每一位对应地保存在一个长为k的数组l,l[i][j]的值就表示第i个数的第j位是1还是0。
      令p[i][j]表示把前i项的第j位累加起来的值,即p[i][j]=l[i][j]+l[i-1][j]+...+l[1][j];
      最关键的一步来了,把这n个数p[i][j]都减去p[i][1],那么只需要寻找一对x,y,使得p[x][i]==p[y][i], 1<=i<=k,记录最大的y-x为答案。
为什么?
      因为如果[x,y]上二进制每一位上的1出现的次数相等,那么
      对于任意的a,b,有p[x][a]-p[y][a] =p[x][b]-p[y][b] (1<=a<=k,1<=b<=k)
                      => p[x][a]-p[x][b]=p[y][a]-p[y][b]
      我令b=1,p[x][i]把每一位上的都减去p[x][1]后,必然p[x][i]=p[y][i] (1<=i<=k)
      所以我只需找到一个最大的y-x即可。
那么此时,问题便转化为了,有个二维数组p,找到一对x,y,使得p[x][i]==p[y][i], 1<=i<=k,求max(y-x)。
显然O(n^2)会超时,于是就用到了hash。。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#define MAXHASH 100001using namespace std;int n,len,l[100020][35],ans,a[100020],fk[100020][35];vector<int> v[100020];int jdz(int n){    return n>0?n:-n;}int f(int c){    int ret =0;    for (int i =1; i <=len; i++)        ret+=fk[c][i]*i;    return jdz(ret);}bool judge(int a,int b){    int i;    for (i=1; i<=len; i++)    {        if (fk[a][i] != fk[b][i])            break;    }    if (i == len+1)        return true;    else        return false;}int main(){    int i,j,t;    scanf("%d%d",&n,&len);    for (i=1; i<=n; i++)    {        scanf("%d",a+i);       // printf("\n");    }    memset(l,0,sizeof(l));    for(i=1;i<=n;i++)    {        t=a[i];        for(j=1;j<=len;j++)        {            l[i][j]=l[i-1][j]+t%2;            t=t/2;        }    }    for(i=1;i<=n;i++)        for(j=1;j<=len;j++)            fk[i][j]=l[i][j]-l[i][1];    for (i=0; i<100020; i++)        v[i].clear();    ans=0;    for (i=0; i<=n; i++)    {        t=f(i);        t%=MAXHASH;        for (j=0; j<v[t].size(); j++)        {            if (judge(v[t][j],i))            {                ans=ans<jdz(i-v[t][j])?jdz(i-v[t][j]):ans;                break;            }        }        if (j == v[t].size())            v[t].push_back(i);    }    printf("%d\n",ans);}


原创粉丝点击