时空限制 1000ms / 128MB

题目描述

作为光荣的济南泉历史研究小组中的一员,铭铭收集了历史上x个不同年份时不同泉区的水流指数,这个指数是一个小于. 2^30的非负整数。第i个年份时六个泉区的泉水流量指数分别为 A(i,l),A(i,2),A(i,3),A(i,4), A(i,5)与 A(i,6)。

现在铭铭希望知道有多少对不同的年份:i和j,满足这两年恰好有K个泉区的泉水流S指数对应相同。

输入输出格式

输入格式:

第一行有2个整数,分别是N和K

之后N行,每行有6个整数。第i行的第j个数字A(i,j)表示第i个年份中第j个泉区的泉水流量指数。

输出格式:

一个整数表示有多少对不同的年份满足恰有K个区的泉水流量指数对应相同。

输入输出样例

输入样例#1:
复制

3 3
1 2 3 4 5 6
1 2 3 0 0 0
0 0 0 4 5 6
输出样例#1: 复制

2

说明

对于 100%的数据, 0<=K <=6, 且所有数据中K是等概率出现的, 即对于任意的 0<=x都有大约 1/7 的数据中 K=x. N<=100000


解:稍加思索,发现我们可以枚举是哪k个相等,但是这样会算重,所以容斥一下。发现26 = 64,有搞头。

这样问题转化成了给定一个6元组组成的序列,判断其中有多少个相等的。显然只要hash就行了。那么如何对一个6元组hash呢?red sun一语惊醒我:字符串hash啊。

注意这题容斥的时候要乘组合数,可能只有我没乘组合数还一直以为是hash的锅......

 #include <bits/stdc++.h>

 typedef unsigned long long uLL;
typedef long long LL;
const int N = ;
const uLL B = , MO = ; uLL pwB[], h[N][], pw2[], h2[N][];
int a[N][], n, k, cnt[], pw[N];
LL C[][]; inline uLL getHash(int x) {
uLL ans = ;
for(int i = ; i < ; i++) {
ans = ans * B + (x % ) + '';
x /= ;
}
return ans;
}
inline uLL getHash2(int x) {
uLL ans = ;
for(int i = ; i < ; i++) {
ans = (ans * B % MO + (x & ) + '') % MO;
x >>= ;
}
return ans;
} namespace Hash {
struct Node {
int cnt, nex;
uLL val, val2;
}node[N]; int tp;
const int mod = ;
int e[mod];
inline int insert(uLL v, uLL v2) {
int x = v % mod;
for(int i = e[x]; i; i = node[i].nex) {
if(node[i].val == v && node[i].val2 == v2) {
return node[i].cnt++;
}
}
node[++tp].val = v;
node[tp].val2 = v2;
node[tp].cnt = ;
node[tp].nex = e[x];
e[x] = tp;
return ;
}
inline void clear() {
memset(e, , sizeof(e));
tp = ;
return;
}
} int main() {
for(int i = ; i <= ; i++) {
C[i][] = C[i][i] = ;
for(int j = ; j < i; j++) {
C[i][j] = C[i - ][j] + C[i - ][j - ];
}
}
scanf("%d%d", &n, &k);
for(int i = ; i <= n; i++) {
for(int j = ; j < ; j++) {
scanf("%d", &a[i][j]);
h[i][j] = getHash(a[i][j]);
h2[i][j] = getHash2(a[i][j]);
}
} int lm = ( << );
for(int s = ; s < lm; s++) {
cnt[s] = + cnt[s - (s & (-s))];
}
pw2[] = pwB[] = ;
for(int i = ; i < ; i++) {
pw[ << i] = i;
}
for(int i = ; i < ; i++) {
pwB[i + ] = pwB[i] * B;
pw2[i + ] = pw2[i] * B % MO;
}
LL fin = ;
for(int s = ; s < lm; s++) {
if(cnt[s] < k) {
continue;
}
LL ans = ;
Hash::clear();
for(int i = ; i <= n; i++) {
uLL temp = , t2 = ;
int ss = s;
while(ss) { int t = pw[ss & (-ss)];
temp = temp * pwB[] + h[i][t];
t2 = (t2 * pw2[] % MO + h2[i][t]) % MO; ss ^= ( << t);
}
ans += Hash::insert(temp, t2);
}
ans = ans * C[cnt[s]][k];
if((cnt[s] - k) & ) {
fin -= ans;
}
else {
fin += ans;
}
} printf("%lld\n", fin);
return ;
}

AC代码

洛谷P3298 泉的更多相关文章

  1. 题解 洛谷 P3298 【[SDOI2013]泉】

    考虑到年份数很小,只有 \(6\),所以可以 \(2^6\) 来枚举子集,确定流量指数对应相同的位置,然后通过哈希和排序来计算相同的方案数. 但是这样计算出的是大于等于子集元素个数的方案数,所以还需要 ...

  2. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  3. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  4. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  5. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  6. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  7. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  8. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

  9. 洛谷八月月赛Round1凄惨记

    个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...

随机推荐

  1. sparkStreaming入门

    1.环境 jdk : 1.8 scala : 2.11.7 hadoop:2.7 spark : 2.2.0 2. 开发工具 idea 2017.2 3.maven的pom文件 <depende ...

  2. Node中的模块系统

    加载require var 自定义变量名称 = require('模块') 两个作用: 执行被加载模块的代码 得到被加载模块中的exports导出接口对象 导出exports node中是模块作用域, ...

  3. Android开发 音视频开发需要了解的专业术语知识

    前言 在摸索一段时间的音视频开发后,越来越发现这个坑的深度真是特别的深. 除了了解Android自带的音视频处理API以外,还得了解一些视频与音频方面的知识.这篇博客就是主要讲解这方面的专业术语.内容 ...

  4. commons lang3的StringUtils中isEmpty()方法和isBlank()方法的区别

    先给结论: 1. StringUtils.isEmpty()中的空格作非空处理2. StringUtils.isNotEmpty()是StringUtils.isEmpty()取反后的结果3. Str ...

  5. 四. (TDZ)展示性死区

    在ES6中怎么使用 var Let const ? 1.var 声明之前 2. let 声明之前 3. const声明之前

  6. Java 的 JJWT 实现 JWT

    JJWT是一个提供端到端的JWT创建和验证的Java库 依赖 <dependency> <groupId>io.jsonwebtoken</groupId> < ...

  7. 并发和多线程(九)--AbstractQueuedSynchronizer排他锁基本原理

    AbstractQueuedSynchronizer简称为AQS,AQS是ReentrantLock.CountdownLatch.CycliBarrier等并发工具的原理/基础,所以了解AQS的原理 ...

  8. 二分图——多重匹配模板hdu1669

    好像多重匹配一般是用网络流来做的.. 这是匈牙利算法的模板:lim是每个组的上界 思路是每个组都可以匹配lim个点,那么当点x遇到的组匹配的点数还没有超过lim时,直接匹配即可 如果已经等于了lim, ...

  9. 容器安全与EDR的异同

    以Docker为代表的容器技术,直接运行于宿主机操作系统内核,因此对于容器安全,很多人会有着这样的疑问:EDR(Endpoint Detection and Response)等主机安全方案,能否直接 ...

  10. C++ 字符串、string、char *、char[]、const char*的转换和区别

    1.字符串 字符串本质就是一串字符,在C++中大家想到字符串往往第一反应是std::string(后面简称string) 字符串得从C语言说起,string其实是个类,C语言是没有class的,所以C ...