洛谷P3298 泉
题目描述
作为光荣的济南泉历史研究小组中的一员,铭铭收集了历史上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个区的泉水流量指数对应相同。
输入输出样例
说明
对于 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 泉的更多相关文章
- 题解 洛谷 P3298 【[SDOI2013]泉】
考虑到年份数很小,只有 \(6\),所以可以 \(2^6\) 来枚举子集,确定流量指数对应相同的位置,然后通过哈希和排序来计算相同的方案数. 但是这样计算出的是大于等于子集元素个数的方案数,所以还需要 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
- 洛谷P1538迎春舞会之数字舞蹈
题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...
- 洛谷八月月赛Round1凄惨记
个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...
随机推荐
- angular 级联选择
HTML: <link rel="stylesheet" href="views/tree/checkbox.css"/> <div clas ...
- C++ 系列:Boost Thread 编程指南
转载自:http://www.cppblog.com/shaker/archive/2011/11/30/33583.html 作者: dozbC++ Boost Thread 编程指南0 前言1 创 ...
- bzoj4144 Petrol
题意:给你一张n个点m条边的带权无向图.其中由s个点是加油站.询问从x加油站到y加油站,油箱容量<=b,能否走到? n,m,q,s<=20W,b<=2e9. 标程: #include ...
- Nginx的安装--------tar包安装
Nginx的安装,在网上搜索是很多的结果,但是 真的安装起来却花费了不少 心思,总结起来就是依赖包安装了,但是没有指定对的路径,在安装的过程中遇到过两个问题: ①make[1]: *** [/usr/ ...
- JavaScript设置body高度为浏览器高度的方法
document.getElementsByTagName('body')[0].style.height = window.innerHeight+'px';
- Python-基本运算符与流程控制
目录 基本运算符 算术运算符 比较运算符 赋值运算符 逻辑运算符 身份运算符 位运算符 成员运算符 运算符优先级 流程控制 if 判断 单分支结构 双分支结构 多分支结构 while 循环 while ...
- 第七章 Odoo 12开发之记录集 - 使用模型数据
在上一篇文章中,我们概览了模型创建以及如何从模型中载入和导出数据.现在我们已有数据模型和相关数据,是时候学习如何编程与其进行交互 了.模型的 ORM(Object-Relational Mapping ...
- go中简单使用kafka
windows上kafka的安装 1.安装jdk 下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jre8-download ...
- springboot导入excel到mysql
@Controller @RequestMapping(path = "/excel") public class ImportController { @Autowired pr ...
- VS2010文件包含
一. 关于iostream.h VS2010的iostream不加.h在后面(加.h的是旧版本),把iostream作为类,正确使用方法: #include<iostream> using ...