POJ3274 -Gold Balanced Lineup- HASH+前缀和

来源:互联网 发布:python列表转换成字典 编辑:程序博客网 时间:2024/05/01 07:14

http://poj.org/problem?id=3274

题意,给出n,k,k表示接下来的数 用k位二进制表示,

给出n个数,  

求出 最长的一个区间,满足:  该区间整体上,二进制下的每一位(1到k)上 “1”的个数之和 都相等。

 

思路:  首先是先把n个数都转成一个 【n】【k】的01数组,然后怎么找这个区间【i,j】呢?   

sum[i][x] 表示 从1到第i头牛时,一共在x位一共有多少个1

因为要求这个区间【i,j】满足   sum[i][0]-sum[j][0] = sum[i][1]=sum[j][1] =......=sum[i][k]=sum[j][k];

即,从i到j,每一位的增量相等,

将上式左右交换一下可得:

sum[i][1]-sum[i][0]=sum[j][1]-sum[j][0] 

....................

sum[i][k]-sum[i][0] =sum[j][k]-sum[j][0]


设CC[x][k]=sum[i][k]-sum[i][0]

显然,等号左边就是  第i头牛时, 把它的sum数组的每一位减去 第0位得到的一个数组CC[i]

如果cc[i] 的每一位 等于cc[j],那么就会符合 从第i到第j条牛之间   每一位的增量相等.


那么我们预处理得到cc数组之后,直接把这个cc[i]hash成一个 数, 一会排个序,判断hash值相同的 数 相差最远的便是答案


trick,  这样得到的是 cc[j]-cc[i]一定会是 【每一位增量相等】,那么max长度就是j-i, 但是如果存在 cc[i]这个节点本身就是 每一位 均等时, (也就是i的每一位都是1 或0) 此时长度应为  j-i +1 

所以只在放多 一个 每一位全是0的节点即可



<span style="font-size:14px;">#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;typedef unsigned __int64 ull;ull p=239; __int64 tm[100005];__int64 single[100005][35]; __int64 sum[100005][35];struct node{ull ss;__int64 pos;node(){}};node ss[100005];__int64 cmp(  node a,  node b)  { if (a.ss!=b.ss)return a.ss<b.ss; else  return a.pos<b.pos;}int main(){ull n,i,j,k; scanf("%I64d%I64d",&n,&k);ull tmp;for (i=0;i<k;i++)single[1][i]=0;for (i=2;i<=n+1;i++){scanf("%I64d",&tm[i]); ull times=k,tmp=tm[i];while(times--){single[i][times]=tmp%2;//求每一位tmp>>=1;}}for (i=1;i<=n+1;i++){for (j=0;j<k;j++){sum[i][j]=single[i][j]+sum[i-1][j];//前缀和}}for (i=1;i<=n+1;i++){ull tmp=0;for (j=0;j<k;j++){sum[i][j]-=sum[i][k-1];//减去最右边tmp=tmp*p+sum[i][j];//拉链法求hash值}ss[i].ss=tmp;//hash值ss[i].pos=i;//位置}sort(ss+1,ss+n+1+1,cmp); ull maxx=0;for (i=1;i<=n+1;i++){ull tmpi=i;while (ss[i].ss==ss[i+1].ss&&i<=n )//选择 相同hash值,距离最远的2个数i++;if (ss[i].pos-ss[tmpi].pos>maxx)//更新maxmaxx=ss[i].pos-ss[tmpi].pos;}printf("%I64d\n",maxx);return 0;}</span>



0 0
原创粉丝点击