POJ 3474 Gold Balanced Lineup Hash

题意一开始不是很明确, 后来发现是每一种特征出现的次数相同

这样一来就变成简单hash问题了,如果把每个特征看看做是一个(n+1)进制数的话,对奶牛序列求一下前缀和,如果i - j这一段每一种特征出现的次数相同的话,把i - 1点和j点的每一位减去所有位中的最小值之后,必然相等,所以hash判断一下就好。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <bitset>
#include <list>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <stack>
#include <sstream>
#include <numeric>
#include <fstream>
#include <functional>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 100000 + 10;
const int maxk = 30;
const int mod = 65536;
int n,k;

struct Node {
    int data[maxk];
    Node(int val = 0) {
        int pos = 0;
        memset(data,0,sizeof(data));
        while(val) {
            data[pos++] = val & 1;
            val >>= 1;
        }
    } 

    bool operator == (const Node &node) const {
        for(int i = 0;i < k;i++) if(node.data[i] != data[i]) return false;
        return true;
    }
};

Node operator + (Node a,Node b) {
    for(int i = 0;i < k;i++) {
        a.data[i] += b.data[i];
    }
    return a;
}


void con(Node &node) {
    int minval = INF;
    for(int i = 0;i < k;i++)
        minval = min(minval,node.data[i]);
    for(int i = 0;i < k;i++) 
        node.data[i] -= minval;
}

int gethash(const Node &node) {
    int ret = 0;
    for(int i = 0;i < k;i++) {
        ret = ret * (n + 1) + node.data[i];
    }
    return ret & (mod - 1);
}


Node cow[maxn],val[maxn];
int head[mod],nxt[maxn],pos[maxn],sz;

int ask(const Node &node,int p) {
    int hc = gethash(node);
    for(int i = head[hc];~i;i = nxt[i]) {
        if(val[i] == node) return pos[i];
    }
    val[sz] = node; pos[sz] = p;
    nxt[sz] = head[hc]; head[hc] = sz++;
    return p;
}

int main() {
    while(scanf("%d%d",&n,&k) != EOF) {
        memset(head,-1,sizeof(head));
        sz = 0;
        for(int i = 1;i <= n;i++) {
            int tmp; scanf("%d",&tmp);
            cow[i] = cow[i - 1] + Node(tmp);
        }
        for(int i = 1;i <= n;i++) con(cow[i]);
        int ans = 0;
        for(int i = 0;i <= n;i++) {
    //        for(int j = 0;j < k;j++) printf("%d ",cow[i].data[j]); putchar('\n');
            int pos = ask(cow[i],i);
            ans = max(ans,i - pos);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2014-09-01 20:38  acm_roll  阅读(132)  评论(0编辑  收藏  举报