[Sdoi2013] [bzoj 3198] spring (hash+容斥原理)
题目描述
给出nnn个666维坐标,求有多少对点对满足恰好mmm个位置相等
1<=n<=1051<=n<=10^51<=n<=105
0<=k<=60<=k<=60<=k<=6
坐标数值在2302^{30}230以内
题目分析
这道题一看就是hash容斥原理,用mmm个位置对应相等−(m+1)-(m+1)−(m+1)个位置对应相等+(m+2)+(m+2)+(m+2)个位置对应相等的…
但是不能简简单单直接+/−+/-+/−,根据广义容斥,还要乘上容斥系数CkmC_{k}^{m}Ckm
双HashHashHash,过程中遇到Hash1Hash1Hash1相同但Hash2Hash2Hash2不同的就往后平移,用数组存一下Hash1Hash1Hash1为kkk时的Hash2Hash2Hash2值与CntCntCnt值
注意此处ModModMod数要大于nnn
考试时没用双Hash,想到了做法,奈何代码太丑,这题爆0了…
AC code
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int MAXN = 100005;
const int P1 = 137, Mod1 = 9999997;
const int P2 = 167, Mod2 = 7394895;
int num[MAXN][6], c[7][7], kase, n, m;
struct MyHash
{
LL y; int flag, cnt; //y存的是Hash1为当前下标i时的Hash2值
//flag是用int打标记,就不用每次清零了
bool Exist() { return flag == kase; }
}h[Mod1];
LL Ans;
void init()
{
for(int i = 0; i < 7; ++i)
{
c[i][0] = c[i][i] = 1;
for(int j = 1; j < i; ++j)
c[i][j] = c[i-1][j-1] + c[i-1][j];
}
}
inline void MyUnique(LL &x, LL o)
{
while(h[x].Exist() && h[x].y != o) (++x) %= Mod1;
}
bool used[7];
void dfs(int pos, int tot)//枚举当前是求哪几个位置
{
if(pos == 6)
{
if(tot < m) return; //小于m的不用处理
LL sum = 0; ++kase;
for(int i = 1; i <= n; ++i)
{
LL hsh1 = 0, hsh2 = 0;
for(int j = 0; j < 6; ++j) if(used[j])
hsh1 = (hsh1 * P1 % Mod1 + num[i][j]) % Mod1,
hsh2 = (hsh2 * P2 % Mod2 + num[i][j]) % Mod2;
MyUnique(hsh1, hsh2);
if(h[hsh1].flag < kase)
h[hsh1].cnt = 0, h[hsh1].flag = kase;
h[hsh1].y = hsh2, sum += (h[hsh1].cnt++);
}
Ans += sum * (((tot-m)&1) ? -1 : 1) * c[tot][m]; //容斥
return;
}
used[pos] = 1;
dfs(pos+1, tot+1);
used[pos] = 0;
dfs(pos+1, tot);
}
int main ()
{
scanf("%d%d", &n, &m); init();
for(int i = 1; i <= n; ++i)
for(int j = 0; j < 6; ++j)
scanf("%d", &num[i][j]);
dfs(0, 0);
printf("%lld\n", Ans);
}
[Sdoi2013] [bzoj 3198] spring (hash+容斥原理)的更多相关文章
- [BZOJ 3198] [Sdoi2013] spring 【容斥 + Hash】
题目链接:BZOJ - 3198 题目分析 题目要求求出有多少对泉有恰好 k 个值相等. 我们用容斥来做. 枚举 2^6 种状态,某一位是 1 表示这一位相同,那么假设 1 的个数为 x . 答案就是 ...
- bzoj 3198 [Sdoi2013]spring(容斥原理+Hash)
Description Input Output Sample Input 3 3 1 2 3 4 5 6 1 2 3 0 0 0 0 0 0 4 5 6 Sample Output 2 HINT [ ...
- BZOJ 3198: [Sdoi2013]spring [容斥原理 哈希表]
3198: [Sdoi2013]spring 题意:n个物品6个属性,求有多少不同的年份i,j满足有k个属性对应相等 一开始读错题了,注意是对应相等 第i个属性只能和第i个属性对应 容斥一下 \[ 恰 ...
- 3198: [Sdoi2013]spring【容斥原理+hash】
容斥是ans= 至少k位置相等对数C(k,k)-至少k+1位置相等对数C(k+1,k)+至少k+2位置相等对数*C(k+2,k) -- 然后对数的话2^6枚举状态然后用hash表统计即可 至于为什么要 ...
- BZOJ 3198 SDOI2013 spring
为什么SDOI省选一年考两次容斥原理? 我们很容易发现>=k个相等时很好计算的 但是我们要求恰好k个,那么我们容斥即可 至于计算>=k个相等,首先我们枚举相等位置,对每个串对应位置做一遍h ...
- 【BZOJ 3098】 Hash Killer II
Description 这天天气不错,hzhwcmhf神犇给VFleaKing出了一道题:给你一个长度为N的字符串S,求有多少个不同的长度为L的子串.子串的定义是S[l].S[l + 1].... S ...
- BZOJ 4455: [Zjoi2016]小星星 [容斥原理 树形DP]
4455: [Zjoi2016]小星星 题意:一个图删掉一些边形成一棵树,告诉你图和树的样子,求让图上的点和树上的点对应起来有多少方案 看了很多题解又想了一段时间,感觉题解都没有很深入,现在大致有了自 ...
- BZOJ 3771 Triple FFT+容斥原理
解析: 这东西其实就是指数型母函数? 所以刚开始读入的值我们都把它前面的系数置为1. 然后其实就是个多项式乘法了. 最大范围显然是读入的值中的最大值乘三,对于本题的话是12W? 用FFT优化的话,达到 ...
- bzoj 2839 : 集合计数 容斥原理
因为要在n个里面选k个,所以我们先枚举选的是哪$k$个,方案数为$C_{n}^k$ 确定选哪k个之后就需要算出集合交集正为好这$k$个的方案数,考虑用容斥原理. 我们还剩下$n-k$个元素,交集至少为 ...
随机推荐
- apache 代理配置
apache 2.4.6版本 <VirtualHost *:8080> ServerName 21.12.13.146 DocumentRoot /root/gbhu ErrorLog / ...
- C++知识点总结篇
const在不同位置时的不同意义 指针类型前:声明一个指向常量的指针,程序中不能通过指针来改变它所指向的值,但指针本身的值可以改变,即指针可以指向其他数据: "*"号和指针名之间, ...
- Python3遍历指定文件夹下所有文件及文件夹
采用os模块儿: import os def get_filelist(dir): for home, dirs, files in os.walk(dir): print("####### ...
- C++ 数组和vector的基本操作
1.静态数组的基本操作 int a[5] = {0, 3, 4, 6, 2}; 1.1 数组的遍历 1.1.1 传统的for循环遍历 int size = sizeof(a) / sizeof(*a) ...
- 生成ftp文件的目录树
依赖 <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</a ...
- FPS 游戏实现D3D透视
FPS游戏可以说一直都比较热门,典型的代表有反恐精英,穿越火线,绝地求生等,基本上只要是FPS游戏都会有透视挂的存在,而透视挂还分为很多种类型,常见的有D3D透视,方框透视,还有一些比较高端的显卡透视 ...
- js 遍历树的层级关系的实现
1.遍历树的层级关系 1)先整理数据 2)找到id和数据的映射关系 3)然后找到父节点的数据,进行存储 test() { const list = [ { id: ", parentId: ...
- shell 实战 -- 基于一个服务启动,关闭,状态检查的脚本
功能说明: check:检查服务状态,在开启,关闭,状态检查时都会用到这个函数,所以封装起来放到最前面 start:开启服务 stop:关闭服务 fstop:强制关闭 status:检查服务状态 ru ...
- print函数用法总结
输出print函数总结: 1,字符串和数字类型 2,变量(数值,布尔,列表,字典) 3,格式化输出 格式化输出总结: (1)%:标记转换说明符的开始 (2)转换标志: - 表示左对齐:+ 表示在转换值 ...
- Python 使用gevent实现多任务
import gevent import time # 如果需要默认的 time.sleep(0.5) 需要打补丁 from gevent import monkey monkey.patch_all ...