[HAOI 2011]Problem c
Description
Input
第一行一个整数T,表示数据组数
对于每组数据,第一行有三个整数,分别表示n、m、M
若m不为0,则接下来一行有m对整数,p1、q1,p2、q2 ,…, pm、qm,其中第i对整数pi、qi表示第pi个人的编号必须为qi
Output
对于每组数据输出一行,若是有解则输出YES,后跟一个整数表示方案数mod M,注意,YES和数之间只有一个空格,否则输出NO
Sample Input
4 3 10
1 2 2 1 3 1
10 3 8882
7 9 2 9 5 10
Sample Output
NO
HINT
100%的数据满足:1≤T≤10,1≤n≤300,0≤m≤n,2≤M≤109,1≤pi、qi≤n 且保证pi互不相同。
题目大意
一个序列合法等价于编号$≤i$的人至少有$i$个。有些人钦定了座位。问合法序列多少个。
题解
难道就我一个人纠结题意纠结这么久么??
令$f_{i,j}$表示编号$≤i$的人有$j$个的方案数,$cnt_i$表示确定编号为$i$的人的个数,$sum_i$表示编号可以$≤i$的人的个数。
则:$$f_{i,j}=\sum_{k=cnt_i}^{j-i+1}f_{i-1,j-k}*C_{sum_i-cnt_i-(j-k)}^{k-cnt_i}$$
显然$i<=j$,那么我们可以考虑如何从$i-1$转移到$i$。因为是从$i-1$转移过来,那么显然我们需要知道编号确定为$i$的人究竟有多少个。所以我们可以枚举这一位,也就是$i$,编号恰好为$i$的人数$k$。那么这个人数$k$显然最少为$cnt[i]$,也就是编号必须为$i$的人数,另外我们需要知道小于等于$i$的人有$j$个,所以同样需要枚举。$j$的范围是$i$到$sum[i]$(最多为$sum[i]$,相当于是能选编号小于等于$i$的最大人数)。所以上一位一共选了$j-k$个人(这一位新选了$k$个(注意:$k≤j-i+1$,因为上一位最少选$i-1$个),一共是$j$个人),所以就可以从$f_{i-1,j-k}$转移过来。那么这一位一共要选出$k-cnt[i]$个人编号为$i$,因为$cnt[i]$是必须要编号为$i$的人数,所以剩下的才是可供自由支配的。然后总人数呢?就是$sum[i]-(j-k)$也就是说这一位最多选$sum[i]$,上一位选了$(j-k)$,可知这一位最多选$sum[i]-cnt[i]-j+k$个人,也就是可以自由支配的总数。所以只需要把上一位的方案数$f_{i-1,j-k}$乘上一个组合数就可以得到这次的$f_{i,j}$。所以我们要预处理一下组合数。记得取模!
//It is made by Awson on 2017.10.19
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Abs(x) ((x) < 0 ? (-(x)) : (x))
using namespace std;
const int N = ; int C[N+][N+];
int n, m, M, p, q;
int cnt[N+], sum[N+];
int f[N+][N+]; void work() {
scanf("%d%d%d", &n, &m, &M);
memset(cnt, , sizeof(cnt)); memset(f, , sizeof(f));
for (int i = ; i <= n; i++) {
C[i][] = ;
for (int j = ; j <= i; j++) C[i][j] = (C[i-][j-]+C[i-][j])%M;
}
for (int i = ; i <= m; i++) {
scanf("%d%d", &p, &q); cnt[q]++;
}
sum[] = n-m;
for (int i = ; i <= n; i++) {
sum[i] = sum[i-]+cnt[i];
if (sum[i] < i) {
printf("NO\n"); return;
}
}
printf("YES ");
f[][] = ;
for (int i = ; i <= n; i++)
for (int j = i; j <= sum[i]; j++)
for (int k = cnt[i]; k <= j-i+; k++)
(f[i][j] += (LL)f[i-][j-k]*C[sum[i]-cnt[i]-(j-k)][k-cnt[i]]%M) %= M;
printf("%d\n", f[n][n]);
}
int main() {
int t; cin >> t;
while (t--) work();
return ;
}
[HAOI 2011]Problem c的更多相关文章
- [BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)
[BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明) 题面 T组询问,每次给出a,b,c,d,k,求\(\sum _{i=a}^b\sum _{j=c}^d[ ...
- [HAOI 2011] Problem A
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2298 [算法] 考虑用总人数 - 最多人说真话 显然 , 对于每个人 , 如果他说的 ...
- [HAOI 2011]Problem b
Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...
- [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)
[BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), ...
- 【BZOJ 2301】【HAOI 2011】Problem b
今天才知道莫比乌斯反演还可以这样:$$F(n)=\sum_{n|d}f(d) \Rightarrow f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)$$我好弱,,,对于$$F( ...
- 数学(莫比乌斯反演):HAOI 2011 问题B
题目描述: 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 输入格式: 第一行一个整数n,接下来n ...
- [HAOI 2011]向量
Description 题库链接 给你一对数 \(a,b\) ,你可以任意使用 \((a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b ...
- HDU 2011 多项式求和
http://acm.hdu.edu.cn/showproblem.php?pid=2011 Problem Description 多项式的描述如下:1 - 1/2 + 1/3 - 1/4 + 1/ ...
- Warsaw U Contest Petrozavo dsk Summer 2011 Training Camp, Monday, September 5, 2011
Warsaw U Contest Petrozavo dsk Summer 2011 Training Camp, Monday, September 5, 2011 Problem A.Chocol ...
随机推荐
- beta冲刺6-咸鱼
前言:此篇是补昨天凌晨的.后面有更新但是太晚了就没有即使更新.所以现在过来更新一下. 昨天的未完成: 用户测试+测试报告 目前剩下的功能点:输入内容检测 我的社团输出显示格式调整. 今天的完成: 我的 ...
- C语言博客作业—数组
一.PTA实验作业 题目1:简化的插入排序 1. 本题PTA提交列表 2. 设计思路 (1)定义n,number,i,j,temp; (2)输入n; (3)定义数组a[n+1]; //把所有的数都放入 ...
- Beta冲刺集合
1.Day1 http://www.cnblogs.com/bugLoser/p/8075868.html 2.Day2 http://www.cnblogs.com/bugLoser/p/80758 ...
- Java作业-集合
1. 本周学习总结 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 public boolean contains(Object o) { r ...
- XFTP连接主机文件名显示中文乱码且不能下载的解决方法
Xftp连接主机文件名显示中文乱码且不能下载的本地解决方法 原因:Xftp编码格式问题 解决方法:把Xftp的编码格式增加UTF-8 具体步骤:打开Xftp,文件-属性,在打开的属性界面中打开&quo ...
- vue class与style 绑定详解——小白速会
一.绑定class的几种方式 1.对象语法 直接看例子: <div id="app3"> <div :class="{'success':isSucce ...
- python虚拟环境搭建大全(转)
Pipenv & 虚拟环境 本教程将引导您完成安装和使用 Python 包. 它将向您展示如何安装和使用必要的工具,并就最佳做法做出强烈推荐.请记住, Python 用于许多不同的目的.准确地 ...
- Spring mvc中junit测试遇到com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException错误怎么解决
今天遇到图片中的错误,纠结了一下,弄清楚了怎么从控制台中读取错误信息,并修改错误. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: ...
- HashMap 的底层原理
1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1 ...
- Python模块 - os , sys.shutil
os 模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录: ...