HDU5852 Intersection is not allowed!
The size of the chessboard is N*N.
The pieces are initially placed on the top cells of the board.
A piece located on (r, c) can be moved by one cell right to (r, c + 1) or one cell down to (r+1, c).
Your task is to count how many different ways to move all pieces to the given positions at the bottom of the board.
Furthermore, the paths of the pieces mustn’t intersect each other.
Each test case begins with a line containing two
integers-N(1<=N<=100000) and K(1<=K<=100) representing the
size of the chessboard and the number of pieces respectively.
The second line contains K integers: 1<=a1<a2<
…<aK<=N representing the initial positions of the pieces. That is,
the pieces are located at (1, a1), (1, a2), …, (1, aK).
Next line contains K integers: 1<=b1<b2<…<bK<=N
representing the final positions of the pieces. This means the pieces
should be moved to (N, b1), (N, b2), …, (N, bK).
OutputPrint consecutive T lines, each of which represents the number of different ways modulo 1000000007.Sample Input
1
5 2
1 2
3 4
Sample Output
50
数学问题 容斥 矩阵行列式 脑洞题
假如只有一个起点一个终点,显然是一个基本的组合数问题,从所有步数中选n-1步向下走,方案为 $ ans = C(b-a+n-1,n-1) $
如果有两个起点两个终点,则是总方案数减去路径交叉的方案数。路径相交可以理解为两人交换了目的地,所以方案为
$ ans = C(b_1-a_1+n-1,n-1)*C(b_2-a_2+n-1,n-1) - C(b_1-a_2+n-1,n-1)*C(b_2-a_1+n-1,n-1)$
显然枚举起点和终点有几对逆序对,可以容斥计算出答案,显然这样TLE了
但这个逆序对数量决定加还是减的容斥可以让我们联想到另一个东西——矩阵行列式。
从矩阵的每一行选一列,将选的每一个位置的值乘起来,乘以(-1)^(逆序对数),即是这一部分对行列式值的贡献,所有的选法的贡献叠加起来,就是矩阵行列式的值。
那么我们只要将每个(u to v)的关系用矩阵表示,再求矩阵行列式的值就是答案了。
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
const int mxn=;
const int mod=1e9+;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int fac[mxn],inv[mxn];
void init(){
fac[]=fac[]=;inv[]=inv[]=;
for(int i=;i<mxn;i++){
fac[i]=(LL)fac[i-]*i%mod;
inv[i]=((-mod/i*(LL)inv[mod%i])%mod+mod)%mod;
}
for(int i=;i<mxn;i++)inv[i]=(LL)inv[i]*inv[i-]%mod;
return;
}
int ksm(int a,int k){
int res=;
while(k){
if(k&)res=(LL)res*a%mod;
a=(LL)a*a%mod;
k>>=;
}
return res;
}
int f[][];
int Gauss(int n){
int ft=;
for(int i=;i<=n;i++){
if(!f[i][i]){
int p=i;
for(int j=i+;j<=n;j++)if(f[j][i]){p=j;break;}
if(p==i)return ;
for(int j=i;j<=n;i++)swap(f[i][j],f[p][j]);
ft=-ft;
}
int IV=ksm(f[i][i],mod-);
for(int j=i+;j<=n;j++){
int tmp=(LL)f[j][i]*IV%mod;
for(int k=i;k<=n;k++){
f[j][k]=((LL)f[j][k]-(LL)tmp*f[i][k])%mod;
}
}
}
int res=ft;
for(int i=;i<=n;i++){
res=(LL)res*f[i][i]%mod;
}
return (res+mod)%mod;
}
int n,K;
int a[mxn],b[mxn];
int C(int n,int m){
if(n<m)return ;
return (LL)fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int path(int x,int y){
return (LL)C(b[y]-a[x]+n-,n-);
}
void solve(){
memset(f,,sizeof f);
for(int i=;i<=K;i++){
for(int j=;j<=K;j++){
f[i][j]=path(i,j);
}
}
int ans=Gauss(K);
printf("%d\n",ans);
return;
}
int main(){
// freopen("in.txt","r",stdin);
init();
int T=read(),i;
while(T--){
n=read();K=read();
for(i=;i<=K;i++)a[i]=read();
for(i=;i<=K;i++)b[i]=read();
solve();
}
return ;
}
HDU5852 Intersection is not allowed!的更多相关文章
- hdu5852 Intersection is not allowed! 【矩阵行列式】
题意 给出\(n*n\)网格\((n<=10^5)\) 顶部有\(K\)个起点,底部有\(K\)个相对应的终点 每次只能向下或向右走 求有多少种从各个起点出发到达对应终点且路径不相交的路径? 对 ...
- HDU 5852 Intersection is not allowed!(LGV定理行列式求组合数)题解
题意:有K个棋子在一个大小为N×N的棋盘.一开始,它们都在棋盘的顶端,它们起始的位置是 (1,a1),(1,a2),...,(1,ak) ,它们的目的地是 (n,b1),(n,b2),...,(n,b ...
- hdu 5852 :Intersection is not allowed! 行列式
有K个棋子在一个大小为N×N的棋盘.一开始,它们都在棋盘的顶端,它们起始的位置是 (1,a1),(1,a2),...,(1,ak) ,它们的目的地是 (n,b1),(n,b2),...,(n,bk). ...
- HDU 5852 Intersection is not allowed! ( 2016多校9、不相交路径的方案、LGV定理、行列式计算 )
题目链接 题意 : 给定方格中第一行的各个起点.再给定最后一行与起点相对应的终点.问你从这些起点出发到各自的终点.不相交的路径有多少条.移动方向只能向下或向右 分析 : 首先对于多起点和多终点的不相交 ...
- LGV 引理
(其实是贺的:https://www.luogu.com.cn/paste/whl2joo4) 目录 LGV 引理 不相交路径计数 例题 Luogu6657. [模板]LGV 引理 CF348D Tu ...
- FJNU2018低程A 逃跑路线(Lucas + 中国剩余定理 + LGV定理)题解
题目描述 n个人在w*h的监狱里面想要逃跑,已知他们的同伙在坐标(bi,h)接应他们,他们现在被关在(ai,1)现在他们必须要到同伙那里才有逃出去的机会,这n个人又很蠢只会从(x,y)->(x+ ...
- 2016 Multi-University Training Contest 9 solutions BY 金策工业综合大学
A Poor King Tag: Reversed BFS Preprocessing is needed to calculate answers for all positions (states ...
- Lindström–Gessel–Viennot lemma定理 行列式板子
https://blog.csdn.net/qq_37025443/article/details/86537261 博客 下面是wiki上的讲解,建议耐心地看一遍...虽然看了可能还是不懂 http ...
- IIS7.5上的REST服务的Put,Delete操作发生HTTP Error 405.0 - Method Not Allowed 解决方法
WebDAV 是超文本传输协议 (HTTP) 的一组扩展,为 Internet 上计算机之间的编辑和文件管理提供了标准.利用这个协议用户可以通过Web进行远程的基本文件操作,如拷贝.移动.删除等.在I ...
随机推荐
- 阅读 用P4对数据平面进行编程
引言 关于题目,对数据平面进行编程,在之前读过the road to SDN,软件定义网络的思想在于数控分离,其对网络行为的编程暂时只局限于网络控制平面.其转发平面在很大程度上受制于功能固定的包处理硬 ...
- 软工实践Alpha冲刺(3/10)
队名:我头发呢队 组长博客 作业博客 杰(组长) 过去两天完成了哪些任务 继续翻阅Google Material Design 2的官方文档 接下来的计划 音源爬取 还剩下哪些任务 app开发 燃尽图 ...
- TCP系列06—连接管理—5、TCP fastopen(TFO)
一.TFO背景 当前web和web-like应用中一般都是在三次握手后开始数据传输,相比于UDP,多了一个RTT的时延,即使当前很多应用使用长连接来处理这种情况,但是仍然由一定比例的短连接,这额外多出 ...
- Matlab快捷键
1. 在命令窗口(Command Window)中: 1) [上.下键]――切换到之前.之后的命令,可以重复按多次来达到你想要的命令 2) clc――清除命令窗口显示的语句,此命令并不清空当前工作区的 ...
- [计算机网络-应用层] FTP协议
文件传输协议:FTP 如下图所示:用户通过一个FTP用户代理与FTP交互.该用户首先提供远程主机的主机名,使本地主机的FTP客户机进程建立一个到远程主机FTP服务器进程的TCP连接.然后,该用户提供用 ...
- JDK各个版本比较 JDK5~JDK9
JDK5 自动装箱与拆箱: 枚举 静态导入,如:import staticjava.lang.System.out 可变参数(Varargs) 内省(Introspector),主要用于操作JavaB ...
- 【Python】Python SQLAlchemy基本操作和常用技巧
首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,API 也许会有些不同.因为我是搭配 MySQL InnoDB 使用,所以使用其他数据库的也不能完全照搬本文. 接着就从安装 ...
- BZOJ 1996 合唱队(DP)
考虑从最后的队形开始依次还原最初的队形. 对于当前的队形,要么选最左边的,要么选最右边的. 如果选了左边的,那么下次选择的一定是大于它的.右边的同理. 所以定义dp[mark][l][r]为区间[l, ...
- BZOJ 1202 狡猾的商人(带权并查集)
给出了l,r,w.我们就得知了s[r]-s[l-1]=w.也就是说,点l-1和点r的距离为w. 于是可以使用带权并查集,定义dis[i]表示点i到根节点的距离.查询和合并的时候维护一下就OK了. 如果 ...
- Docker的结构(6-13)
一.Docker的结构. Docker命令不清楚的时候可以在命令的最后加上--help Docker和虚拟机的区别? 虚拟机的实现原理是:先模拟出一套硬件,然后在这基础上跑一个操作系统,然后在这个操作 ...