1. 程式人生 > >[Usaco2007 Mar]Gold Balanced Lineup 平衡的隊列

[Usaco2007 Mar]Gold Balanced Lineup 平衡的隊列

res lse 長度 table str 因此 cow typedef inpu

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
第一行給出數字N,K
下面N行每行給出一個數字,代表這頭牛的特征值

Output
求出一個區間值,在這個區間中,所有牛的這K種特征值的總和是相等的.

Sample Input
7 3
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
4

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

這題我們推推柿子,我們首先記錄一下前綴和 sum[i][k],表示到第i頭牛,k的特征值前綴和為k。如果說某段區間滿足條件,那麽肯定有\(sum[r][i]-sum[l-1][i](i\in[1,k])\)都相同,我們單獨拎出兩項\(sum[r][i]-sum[l-1][i]=sum[r][i-1]-sum[l-1][i-1]\),移項得到\(sum[r][i]-sum[r][i-1]=sum[l-1][i]-sum[l-1][i-1]\),因此,我們只需要對每個點記錄一下\(sum[x][i]-sum[x][i-1]\)

,而且由於我們按順序枚舉,那麽最先出現的做左端點必定更優,這樣我們就得到了判斷第i個和第i-1個特征值相同的情況的辦法了。判多個也只需要多次差分即可

然後記錄位置可以用map,當然,這題並不需要排序,因此可以用unordered_map,不過記得手寫hash

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar())  if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=getchar())    x=(x<<1)+(x<<3)+ch-'0';
    return x*f;
}
inline void print(int x){
    if (x>=10)  print(x/10);
    putchar(x%10+'0');
}
const int N=1e5,limit=2333;
int n,k,Ans;
struct S1{
    int v[30];
    S1(){memset(v,0,sizeof(v));}
    bool operator ==(const S1 &x)const{
        for (int i=1;i<k;i++)   if (v[i]!=x.v[i])   return 0;
        return 1;
    }
}tmp;
struct myHash{
    size_t operator ()(const S1 &x)const{
        ui res=0;
        for (int i=1;i<k;i++)   res=res*limit+x.v[i];
        return res;
    }
};
unordered_map<S1,int,myHash>mp;
int cnt[30];
void Extract(int x){for (int i=0;i<k;i++)   cnt[i]+=x&1,x>>=1;}
int main(){
    n=read(),k=read(),mp[tmp]=0;
    for (int i=1;i<=n;i++){
        Extract(read());
        for (int i=1;i<k;i++)   tmp.v[i]=cnt[i]-cnt[i-1];
        if (mp.count(tmp))  Ans=max(Ans,i-mp[tmp]);
        else    mp[tmp]=i;
    }
    printf("%d\n",Ans);
    return 0;
}

[Usaco2007 Mar]Gold Balanced Lineup 平衡的隊列