原题:POJ3274

参考:进击的阿俊


已知有n头牛,用一个K位二进制数Ak,Ak-1,...,A1表示一头牛具有的特征,Ai=1表示具有特征i。现给定按顺序排列的N头牛的k位特征值,称某个连续范围内“特征平衡”,假如在这个范围内,拥有各个特征的牛的数量都相等。求最大“特征平衡”连续范围。

分析:

用sum[i][j]( 1<=i<=n, 1<=k<=j)表示1到第i头牛中具有特征j的牛的数量。问题转化为求解满足sum[i][l] - sum[j][l] = sum[i][1] - sum[j][1](l = 1,2,..,k)的最大i - j的值。很容易想到最简单的方法,通过令d = n to 1,判断是否存在i,使得sum[i + d][j] - sum[i][j] = sum[i + d][1] - sum[i][j],时间复杂度为O(n*n*k)。由于n的最大值能达到100000,必须选择一个更加优化的方法。

1)容易验证,sum[i][l] - sum[j][l] = sum[i][1] - sum[j][1] ( l = 1,2,..,k ) 等价于sum[i][l] - sum[i][1] = sum[j][l] - sum[j][1] ( l = 1,2,...k )。因此令d[i][j] =  sum[i][j] - sum[i][1] ,问题就转化为求解使得d[i][j] = d[i + size][j]的最大size。

2)为进一步简化算法,对于任意 1<= i <=n, 令sig[i] = (d[i][1] + d[i][2] + ... +d[i][k] ) % m (m为一个较大的质数)。这样,若对于i和j, sig[i] != sig[j],那么必定不会满足d[i][] = d[j][],就无需再对它进行验证;若满足sig[i] = sig[j],才需要进一步确定是否有d[i][] = d[j][]。

3)用h[k] (1 <= k <= m,m为以上取模运算的素数)记录满足sig[i] = k的i值。通过令 i = 1 to n,以此更新h[sig[i]]和largest,即可得到结果。


样例输入

7 3
7
6
7
2
1
4
2

样例输出

4


//
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath> using namespace std; const int maxn = 100010;
const int maxk = 31;
int n, k, tmp;
bool cow[maxn][maxk];
int sum[maxn][maxk];
int d[maxn][maxk]; //d 和 sig辅助计算哈希值
int s, size;
const int prime = 49117;
int sig[maxn];
int largest; vector <int> h[prime]; //哈希表 void search(int i, int t)//0 1 \ 2 2 \ 2 3 \ 3 4 \
{
int size = h[i].size();
for (int j = 0; j < size; j++) {
bool flag = 1;
for (int l = 0; l < k; l++) {
//printf("d[h[%d][%d]:%d][%d]:%d ==? d[%d][%d]:%d\n",i,j,h[i][j],l,d[h[i][j]][l],t,l,d[t][l]);
if ( d[ h[i][j] ][l] != d[t][l] ) {
flag = 0;
break;
}
}
if (flag) {
if (t - h[i][j] > largest)
largest = t - h[i][j];
return;
}
}
h[i].push_back(t);
//printf("i:%d push back t:%d\n",i,t);
} int findLargest()
{
largest = 0;
for (int i = 1; i <= n; i++) {
search(sig[i], i);
printf("%d\n",largest);
}
return largest;
} void init()
{
memset(sum, 0, sizeof(sum));
memset(sig, 0, sizeof(sig));
for (int i = 0; i < prime; i++) h[i].clear();
h[0].push_back(0);
for (i = 1; i <= n; i++) {
for (int j = 0; j < k; j++) {
sum[i][j] = sum[i - 1][j] + cow[i][j];
d[i][j] = sum[i][j] - sum[i][0];
sig[i] += d[i][j];
//printf("%d ",d[i][j]);
//printf("%d ",d[i][j]);
}
//printf("%d\n",sig[i]);
/*
for (j = 0; j < k; j++) {
sig[i] += d[i][j];
}
*/
sig[i] = abs(sig[i]) % prime;
}
} int main()
{
//while (1) {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++ ) {
scanf("%d", &tmp);
for (int j = 0; j < k; j++) {
cow[i][j] = tmp % 2;
tmp /= 2;
}
}
init();
findLargest();
printf("%d\n", largest);
//}
return 0;
}

POJ3274-牛的属性-HASH-ACM的更多相关文章

  1. 牛客网暑期ACM多校训练营(第四场):A Ternary String(欧拉降幂)

    链接:牛客网暑期ACM多校训练营(第四场):A Ternary String 题意:给出一段数列 s,只包含 0.1.2 三种数.每秒在每个 2 后面会插入一个 1 ,每个 1 后面会插入一个 0,之 ...

  2. 牛客网暑期ACM多校训练营(第五场):F - take

    链接:牛客网暑期ACM多校训练营(第五场):F - take 题意: Kanade有n个盒子,第i个盒子有p [i]概率有一个d [i]大小的钻石. 起初,Kanade有一颗0号钻石.她将从第1到第n ...

  3. 牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?

    牛客网暑期ACM多校训练营(第二场) 水博客. A.run 题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束.问一共有多少种移动的方式. 个人 ...

  4. 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学

    牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...

  5. 牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献)

    牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献) 链接:https://ac.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy ha ...

  6. 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)

    2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...

  7. 牛客网暑期ACM多校训练营(第七场)Bit Compression

    链接:https://www.nowcoder.com/acm/contest/145/C 来源:牛客网 题目描述 A binary string s of length N = 2n is give ...

  8. 2018牛客网暑假ACM多校训练赛(第五场)H subseq 树状数组

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round5-H.html 题目传送门 - https://www.no ...

  9. 2018牛客网暑假ACM多校训练赛(第四场)E Skyline 线段树 扫描线

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round4-E.html 题目传送门 - https://www.no ...

  10. poj3274 Gold Balanced Lineup(HASH)

    Description Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been abl ...

随机推荐

  1. Cogs 1070. [焦作一中2012] 玻璃球游戏 带权并查集,逆序处理

    题目: http://cojs.tk/cogs/problem/problem.php?pid=1070 1070. [焦作一中2012] 玻璃球游戏 ★   输入文件:marbles.in   输出 ...

  2. Google的一些功能和软件

    本博文的主要内容有 .Google的一些功能和软件 Google的一些功能和软件 1.  iGoogle 2.  Google Earth 3.  Google Talk http://www.goo ...

  3. iOS10-配置获取隐私数据权限声明

    iOS10中,苹果加强了对用户隐私数据的保护,在访问以下数据的时候都需要在info.list重配置privacy,进行声明,否则程序无法正常运行. Contacts, Calendar, Remind ...

  4. thinkphp解决表单令牌问题

    控制器中添加 C('TOKEN_ON',false); 然后再$this->display();即可

  5. NIO与普通IO文件读写性能对比

    最近在熟悉java的nio功能.nio采用了缓冲区的方式进行文件的读写,这一点更接近于OS执行I/O的方式.写了个新旧I/O复制文件的代码,练练手,顺便验证一下两者读写性能的对比,nio是否真的比普通 ...

  6. xml学习篇(二) ----JSON 和XML对比

    在比较JSON和XML之前,我们先来上一堂关于数据格式的简要历史(更准确的说,是关于XML的始祖): 早在1970年,IBM开发了一种叫Generalized Markup Language的标记语言 ...

  7. [notes] ImageNet Classification with Deep Convolutional Neual Network

    Paper: ImageNet Classification with Deep Convolutional Neual Network Achievements: The model address ...

  8. linux 内核分析+使用SystemTap调试新增内核模块

    http://blog.chinaunix.net/uid/14528823/list/1.html?cid=189394

  9. 在Ubuntu 12.10 上安装部署Openstack

    OpenStack系统有几个关键的项目,它们能够独立地安装但是能够在你的云计算中共同工作.这些项目包括:OpenStack Compute,OpenStack Object Storage,OpenS ...

  10. MyBatis Tutorial – CRUD Operations and Mapping Relationships – Part 1---- reference

    http://www.javacodegeeks.com/2012/11/mybatis-tutorial-crud-operations-and-mapping-relationships-part ...