Description
N(1<=N<=100000)头牛,一共K(1<=K<=30)种特色,
每头牛有多种特色,用二进制01表示它的特色ID。比如特色ID为13(1101),
则它有第1、3、4种特色。[i,j]段被称为balanced当且仅当K种特色在[i,j]内
拥有次数相同。求最大的[i,j]段长度。
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
6
7
2
1
4
2
INPUT DETAILS:
The line has 7 cows with 3 features; the table below summarizes the
correspondence:
Feature 3: 1 1 1 0 0 1 0
Feature 2: 1 1 1 1 0 0 1
Feature 1: 1 0 1 0 1 0 0
Key: 7 6 7 2 1 4 2
Cow #: 1 2 3 4 5 6 7
Sample Output
OUTPUT DETAILS:
In the range from cow #3 to cow #6 (of size 4), each feature appears
in exactly 2 cows in this range:
Feature 3: 1 0 0 1 -> two total
Feature 2: 1 1 0 0 -> two total
Feature 1: 1 0 1 0 -> two total
Key: 7 2 1 4
Cow #: 3 4 5 6


#include<cstdio> #include<cstring> #include<algorithm> #include<map> #define LL unsigned long long const int M=2e5+7,P=233; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,ans; int d[M][35]; std::map<LL,int>q; int find(int x){ LL sum=0; for(int i=2;i<=k;i++) sum=sum*P+1LL*d[x][i]; if(!q[sum]&&sum) q[sum]=x; return q[sum]; } int main(){ n=read(); k=read(); for(int i=1;i<=n;i++){ int now=0,x=read(); for(;x;x>>=1) d[i][++now]=x&1; for(int j=1;j<=k;j++) d[i][j]+=d[i-1][j]; } for(int i=1;i<=n;i++){ for(int j=2;j<=k;j++) d[i][j]-=d[i][1]; ans=std::max(ans,i-find(i)); }printf("%d\n",ans); return 0; }
本文介绍了一种解决特定组合优化问题的算法:即给定一定数量的牛及其拥有的特色,找出最大的连续区间使得该区间内的每种特色出现次数相同。通过将牛的特色转化为二进制表示,并使用前缀和与哈希表的方法快速定位到满足条件的最大区间。
295

被折叠的 条评论
为什么被折叠?



