小w的喜糖(candy)
小w的喜糖(candy)
题目描述
废话不多说,反正小w要发喜糖啦!!
小w一共买了n块喜糖,发给了n个人,每个喜糖有一个种类。这时,小w突发奇想,如果这n个人相互交换手中的糖,那会有多少种方案使得每个人手中的糖的种类都与原来不同。
两个方案不同当且仅当,存在一个人,他手中的糖的种类在两个方案中不一样。
输入
第一行,一个整数n。
接下来n行,每行一个整数,第i个整数Ai表示开始时第i个人手中的糖的种类。
输出
一行,一个整数Ans,表示方案数模1000000009。
样例输入
6
1
1
2
2
3
3
样例输出
10
提示
【数据规模和约定】
对于所有数据,1≤Ai≤k。
|
数据点 |
n |
k |
约束 |
|
1 |
≤10 |
≤10 |
无 |
|
2 |
|||
|
3 |
≤20 |
n |
每个人的糖果种类都不一样 |
|
4 |
≤100 |
||
|
5 |
≤2000 |
||
|
6 |
|||
|
7 |
≤200 |
3 |
无 |
|
8 |
|||
|
9 |
|||
|
10 |
|||
|
11 |
≤n |
||
|
12 |
|||
|
13 |
|||
|
14 |
|||
|
15 |
≤2000 |
||
|
16 |
|||
|
17 |
|||
|
18 |
|||
|
19 |
|||
|
20 |
solution
背景(没用)
错排:求1~n的排列ai,满足ai!=i的个数
考虑令
表示
个数字任意放的方案数,
表示
个数字都不放在自己位置上的方案数,通过枚举不在自己位置上的数字的个数容易得到
由二项式反演得到
注意到
,这样我们就得到了他的通项公式,通过将
和组合数展开就可以得到更为简便的通项公式了
---------------某度
有重复元素的排列
好的,接下来才是正经的题解
令f[i][j]表示前i种糖,有j个人拿到了原来的糖的方案数
考虑算f[i][j]
也就是第i种糖,有k个人不合法
就这样啦
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 2005
#define mod 1000000009
using namespace std;
int n,cnt[maxn],t;
long long ans,ny[maxn],f[maxn][maxn],h[maxn];
long long work(long long k,long long num){
long long tmp=1;
while(num){
if(num&1)tmp=tmp*k;
k=k*k;k%=mod;tmp%=mod;num/=2;
}
return tmp;
}
long long C(int n,int m){
long long tmp=0;
tmp=(1LL*h[n]*ny[m]%mod)*ny[n-m];tmp%=mod;
return tmp;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&t);
cnt[t]++;
}
h[0]=1;ny[0]=1;
for(int i=1;i<=n;i++){
h[i]=(1LL*h[i-1]*i)%mod;
ny[i]=work(h[i],mod-2);
}
f[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=n;j++){
for(int k=0;k<=cnt[i];k++){
if (k>j)break;
f[i][j]+=(1LL*f[i-1][j-k]*C(cnt[i],k))%mod*ny[cnt[i]-k];
f[i][j]%=mod;
}
}
int op=1;
for(int i=0;i<=n;i++){
ans+=(1LL*f[n][i]*(h[n-i]*op))%mod;
op=op*(-1);
}
ans=(ans%mod+mod)%mod;
cout<<ans<<endl;
return 0;
}
小w的喜糖(candy)的更多相关文章
- bzoj4665小w的喜糖 dp+容斥
4665: 小w的喜糖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 120 Solved: 72[Submit][Status][Discuss] ...
- bzoj4665 小w的喜糖(dp+容斥)
4665: 小w的喜糖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 222 Solved: 130[Submit][Status][Discuss ...
- 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)
4665: 小w的喜糖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 94 Solved: 53 Description 废话不多说,反正小w要发喜 ...
- 【BZOJ4665】小w的喜糖 容斥+组合数
[BZOJ4665]小w的喜糖 Description 废话不多说,反正小w要发喜糖啦!! 小w一共买了n块喜糖,发给了n个人,每个喜糖有一个种类.这时,小w突发奇想,如果这n个人相互交换手中的糖,那 ...
- [bzoj4665]小w的喜糖_二项式反演
小w的喜糖 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=4665 数据范围:略. 题解: 二项式反演裸题. $f_{i,j}$表示,前$i$种钦 ...
- BZOJ 4665: 小w的喜糖
Sol DP+容斥. 这就是一个错排的扩展...可是想到容斥却仅限于种数的容斥,如果种数在一定范围内我就会做了QAQ. 但是容斥的是一定在原来位置的个数. 发现他与原来的位置无关,可以先把每个同种的糖 ...
- ●BZOJ 4665 小w的喜糖
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4665 题解: 容斥,dp令 v[i] 表示原来拥有i类糖果的人数. (一个套路,首先把每个糖 ...
- BZOJ4665: 小w的喜糖 DP
对于这道题,首先每个人的位置并不影响结果 所以我们可以将相同颜色糖果的人放在一块处理 设 $f_{i,j}$ 表示处理到第 $i$ 种糖果至少有 $j$ 人的糖果和原先的类型相同 枚举当前种类中不满足 ...
- BZOJ4665 : 小w的喜糖
考虑枚举哪些人一定不合法,那么方案数可以通过简单的排列组合算出. 于是设$f[i][j]$表示前$i$种糖果,一共有$j$个人一定不合法的方案数,但是这样并不能保证其他人一定合法,所以需要进行容斥. ...
随机推荐
- springboot集成shiro的session污染问题
问题起因是这样的,有两套系统,系统a和系统b.两套系统均使用shiro做的权限管理,之前部署在两台机器上.使用浏览器打开a系统后另开页签打开b系统,互不干扰都能正常使用,后因业务迁移,两套系统部署到了 ...
- Python实现进度条小程序
一.print()参数介绍 1.end:指定打印结束后添加的字符,默认值为换行符 for j in range(3): print('hello world') for i in range(3): ...
- ubuntu安装R时候增加软件源到sources.list,sudo apt-get update不能更新
http://forum.ubuntu.org.cn/viewtopic.php?t=401717 ubuntu安装R时候增加软件源到sources.list,sudo apt-get update不 ...
- Oracle 配置文件目录
Oracle 配置文件目录 ① 在oracle安装目录下,找D:\oracle\product\10.2.0\client_1\NETWORK\ADMIN中的tnsnames.ora文件,找到之后,配 ...
- Uva 组装电脑 12124 - Assemble
主要运用二分法查找最优解 #include<iostream> #include<string> #include<vector> #include<map& ...
- (82)zabbix如何选择适合的监控类型
zabbix提供十几种监控类型,包括:Zabbix agent, Simple checks, SNMP, Zabbix internal, IPMI, JMX monitoring等等,那我们应该如 ...
- Visual Studio 2017 初次体验
在初次体验中遇到以下问题以及技巧 1. 在出现红色波浪线时为出现错误语法,将鼠标移动到相应位置可以获得相关错误信息 2.在编写代码过程中,行号上出现的小黄灯可以有提示信息 3.List 与 Array ...
- 二十七、MySQL 复制表
MySQL 复制表 如果我们需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等. 如果仅仅使用CREATE TABLE ... SELECT 命令,是无法实现的. 本章节将为大家介绍如何完 ...
- Gearman任务分配
Gearman 实现多数据库数据同步 测试环境:windows(mysql)+ 虚拟机(ubuntu + mysql)+ PHP 1:gearman 的官方文档可以了解gearman,在ubuntu中 ...
- php中 为什么验证码 必须要开启 ob_clean 才可以显示
用ob_clean(),将前面的输出都清除就OK了 这表示你的程序前面有输出,<?php 前有空格.空行.文件有BOM头 ob_clean(); header("content-typ ...
表示
个数字任意放的方案数,
表示
个数字都不放在自己位置上的方案数,通过枚举不在自己位置上的数字的个数容易得到

,这样我们就得到了他的通项公式,通过将
和组合数展开就可以得到更为简便的通项公式了