题目链接:BZOJ - 3198

题目分析

题目要求求出有多少对泉有恰好 k 个值相等。

我们用容斥来做。

枚举 2^6 种状态,某一位是 1 表示这一位相同,那么假设 1 的个数为 x 。

答案就是 sigma((-1)^(x - k) * AnsNow * C(x, k)) 。注意 x 要大于等于 k。

对于一种状态,比如 10110,就是要保证第 1, 3, 4 个值相同。

这些值相同的对数怎么来求呢?使用Hash。

将这些位上的值 Hash 成一个数,然后枚举  [1, i] , 每次求出 [1, i-1] 有多少和 i 相同的,再把 i 加入 Hash 表。

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm> using namespace std; typedef long long LL; const int MaxN = 100000 + 5, Base = 11003, Mod = 10007; int n, k;
int A[MaxN][10]; LL Ans, Temp;
LL C[10][10]; void PrepareC()
{
C[0][0] = 1;
for (int i = 1; i <= 6; ++i)
{
C[i][0] = 1;
for (int j = 1; j <= i; ++j)
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
} struct HashNode
{
int B[10];
int Sum;
HashNode *Next;
} HA[MaxN], *P = HA, *Hash[Mod + 5]; inline bool Cmp(int *x, int *y)
{
for (int i = 0; i < 6; ++i)
if (x[i] != y[i]) return false;
return true;
} int Get(int x, int k)
{
int Num[10];
LL HashNum = 0;
for (int i = 0; i < 6; ++i)
{
HashNum = HashNum * Base % Mod;
if (k & (1 << i))
{
Num[i] = A[x][i];
HashNum += Num[i] % Base;
HashNum %= Mod;
}
else Num[i] = 0;
}
HashNode *Now;
Now = Hash[HashNum];
int ret = 0;
while (Now)
{
if (Cmp(Now -> B, Num))
{
ret = Now -> Sum;
break;
}
Now = Now -> Next;
}
return ret;
} void Add(int x, int k)
{
int Num[10];
LL HashNum = 0;
for (int i = 0; i < 6; ++i)
{
HashNum = HashNum * Base % Mod;
if (k & (1 << i))
{
Num[i] = A[x][i];
HashNum += Num[i] % Base;
HashNum %= Mod;
}
else Num[i] = 0;
}
HashNode *Now;
Now = Hash[HashNum];
bool Flag = false;
while (Now)
{
if (Cmp(Now -> B, Num))
{
Flag = true;
++(Now -> Sum);
break;
}
Now = Now -> Next;
}
if (Flag) return;
++P; P -> Sum = 1;
for (int i = 0; i < 6; ++i) P -> B[i] = Num[i];
P -> Next = Hash[HashNum]; Hash[HashNum] = P;
} int main()
{
scanf("%d%d", &n, &k);
PrepareC();
for (int i = 1; i <= n; ++i)
for (int j = 0; j < 6; ++j)
scanf("%d", &A[i][j]);
int Cnt;
Ans = 0;
for (int i = 0; i < 64; ++i)
{
Cnt = 0;
for (int j = 0; j < 6; ++j)
if (i & (1 << j)) ++Cnt;
if (Cnt < k) continue;
Temp = 0;
memset(Hash, 0, sizeof(Hash));
P = HA;
for (int j = 1; j <= n; ++j)
{
Temp += Get(j, i);
Add(j, i);
}
if ((Cnt - k) & 1) Temp *= -1;
Ans += Temp * C[Cnt][k];
}
printf("%lld\n", Ans);
return 0;
}

  

[BZOJ 3198] [Sdoi2013] spring 【容斥 + Hash】的更多相关文章

  1. bzoj3198[Sdoi2013]spring 容斥+hash

    3198: [Sdoi2013]spring Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1143  Solved: 366[Submit][Sta ...

  2. 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 [ ...

  3. BZOJ 3198: [Sdoi2013]spring [容斥原理 哈希表]

    3198: [Sdoi2013]spring 题意:n个物品6个属性,求有多少不同的年份i,j满足有k个属性对应相等 一开始读错题了,注意是对应相等 第i个属性只能和第i个属性对应 容斥一下 \[ 恰 ...

  4. BZOJ 3198 SDOI2013 spring

    为什么SDOI省选一年考两次容斥原理? 我们很容易发现>=k个相等时很好计算的 但是我们要求恰好k个,那么我们容斥即可 至于计算>=k个相等,首先我们枚举相等位置,对每个串对应位置做一遍h ...

  5. 3198: [Sdoi2013]spring【容斥原理+hash】

    容斥是ans= 至少k位置相等对数C(k,k)-至少k+1位置相等对数C(k+1,k)+至少k+2位置相等对数*C(k+2,k) -- 然后对数的话2^6枚举状态然后用hash表统计即可 至于为什么要 ...

  6. bzoj 3202 [Sdoi2013]项链——容斥+置换+推式子

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3202 可见Zinn博客:https://www.cnblogs.com/Zinn/p/100 ...

  7. BZOJ.2655.calc(DP/容斥 拉格朗日插值)

    BZOJ 洛谷 待补.刚刚政治会考完来把它补上了2333.考数学去了. DP: 首先把无序化成有序,选严格递增的数,最后乘个\(n!\). 然后容易想到令\(f_{i,j}\)表示到第\(i\)个数, ...

  8. BZOJ 4455: [Zjoi2016]小星星(容斥+树形dp)

    传送门 解题思路 首先题目中有两个限制,第一个是两个集合直接必须一一映射,第二个是重新标号后,\(B\)中两点有边\(A\)中也必须有.发现限制\(2\)比较容易满足,考虑化简限制\(1\).令\(f ...

  9. [SDOI2013]泉(容斥)

    /* 容斥加上哈希 首先我们可以2 ^ 6枚举相同情况, 然后对于这些确定的位置哈希一下统计方案数 这样我们就统计出了这些不同方案的情况, 然后容斥一下就好了 */ #include<cstdi ...

随机推荐

  1. fork和exec函数

    #include<unistd.h> pid_t fork(void); 返回:在子进程中为0,在父进程中为子进程IO,若出错则为- fork最困难之处在于调用它一次,它却返回两次.它在调 ...

  2. 为什么java不支持多重继承?

    什么是钻石问题?如下图所示,B和C继承于A,D继承B和C(多重继承),在D中调用A的方法时,无法判断是调用B中的实现还是C的实现,下图继承关系是个菱形,所以该问题又叫做菱形问题. 如果java要解决这 ...

  3. ubuntu首次给root用户设置密码

    用过ubuntu的人都知道,刚安装好root用户是没有密码的,没有密码我们就没法用root用户登录 给root用户设置密码输入命令sudo passwd,然后系统会让你输入密码,这时输入的密码就是ro ...

  4. CentOS 6使用iostat

    iostat/mpstat/sar等命令属于sysstat程序包,所以使用yum安装sysstat即可. yum install sysstat

  5. (转)网站隔几天打不开,多次重启Apache解决办法

    网站打不开了重启一下apache又好了,但过二天又打不开了,只有重启一下才好,基本上二天重起一次,本文主要解决这个问题 工具/原料 linux服务器 网站 方法/步骤   注意观察cpu占用情况{:s ...

  6. 关于wordpress中更换CKEditor编辑器

    wordpress中自带的编辑器实在是功能太简,连插入表格都没有,使用插件的方式太过于麻烦,干脆就直接更换编辑器了,在网上找了一些方法,下文引自http://down.chinaz.com/try/2 ...

  7. OC基础-day02

    #pragma mark - Day02_01_对象的创建与使用 1)如何通过类创建一个对象 1. 类是抽象的,无法直接使用 2. 对象是类的一个具体实现,可以直接使用 3. 语法 类名 *对象名 = ...

  8. 吐槽:Lambda表达式

    前面我曾经讨论过Lambda表达式(也就是匿名表达式)的用法, 这里我就主要强调一下匿名表达式的好处. 首先是不需要写多余的方法体,特别是订阅事件的时候,但是也有一个问题,那就是单个方法会因为匿名表达 ...

  9. C#有关 字符串方法的使用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  10. C# 控制台窗口的显示与隐藏

    1. 定义一个Consolse帮助类,如下: /// <summary> /// 控制台帮助类 /// </summary> public static class Conso ...