There are K pieces on the chessboard.

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.

InputThe first line of input contains an integer T-the number of test cases.

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!的更多相关文章

  1. hdu5852 Intersection is not allowed! 【矩阵行列式】

    题意 给出\(n*n\)网格\((n<=10^5)\) 顶部有\(K\)个起点,底部有\(K\)个相对应的终点 每次只能向下或向右走 求有多少种从各个起点出发到达对应终点且路径不相交的路径? 对 ...

  2. HDU 5852 Intersection is not allowed!(LGV定理行列式求组合数)题解

    题意:有K个棋子在一个大小为N×N的棋盘.一开始,它们都在棋盘的顶端,它们起始的位置是 (1,a1),(1,a2),...,(1,ak) ,它们的目的地是 (n,b1),(n,b2),...,(n,b ...

  3. hdu 5852 :Intersection is not allowed! 行列式

    有K个棋子在一个大小为N×N的棋盘.一开始,它们都在棋盘的顶端,它们起始的位置是 (1,a1),(1,a2),...,(1,ak) ,它们的目的地是 (n,b1),(n,b2),...,(n,bk). ...

  4. HDU 5852 Intersection is not allowed! ( 2016多校9、不相交路径的方案、LGV定理、行列式计算 )

    题目链接 题意 : 给定方格中第一行的各个起点.再给定最后一行与起点相对应的终点.问你从这些起点出发到各自的终点.不相交的路径有多少条.移动方向只能向下或向右 分析 : 首先对于多起点和多终点的不相交 ...

  5. LGV 引理

    (其实是贺的:https://www.luogu.com.cn/paste/whl2joo4) 目录 LGV 引理 不相交路径计数 例题 Luogu6657. [模板]LGV 引理 CF348D Tu ...

  6. FJNU2018低程A 逃跑路线(Lucas + 中国剩余定理 + LGV定理)题解

    题目描述 n个人在w*h的监狱里面想要逃跑,已知他们的同伙在坐标(bi,h)接应他们,他们现在被关在(ai,1)现在他们必须要到同伙那里才有逃出去的机会,这n个人又很蠢只会从(x,y)->(x+ ...

  7. 2016 Multi-University Training Contest 9 solutions BY 金策工业综合大学

    A Poor King Tag: Reversed BFS Preprocessing is needed to calculate answers for all positions (states ...

  8. Lindström–Gessel–Viennot lemma定理 行列式板子

    https://blog.csdn.net/qq_37025443/article/details/86537261 博客 下面是wiki上的讲解,建议耐心地看一遍...虽然看了可能还是不懂 http ...

  9. IIS7.5上的REST服务的Put,Delete操作发生HTTP Error 405.0 - Method Not Allowed 解决方法

    WebDAV 是超文本传输协议 (HTTP) 的一组扩展,为 Internet 上计算机之间的编辑和文件管理提供了标准.利用这个协议用户可以通过Web进行远程的基本文件操作,如拷贝.移动.删除等.在I ...

随机推荐

  1. Android - 时间 日期相关组件

    源码下载地址 : -- CSDN :  http://download.csdn.net/detail/han1202012/6856737 -- GitHub : https://github.co ...

  2. Java之I/O流(第2部分)

    1. 节点类类型: 2. 访问文件: Demo_1: import java.io.FileInputStream; import java.io.FileNotFoundException; imp ...

  3. RXSwift --UITableView之初探

    对于RXSwift中的一些基本概念和说明请参看其他文章,接下来我们使用RXSwift一步一步去构建TableView,从简单到复杂.iOS开发过程中tableView的使用率是最高的,他的一些代理方法 ...

  4. JS DOM视频相关的知识

    1.实现点击a标签改变图片时,如果a的href属性有一个目标网址,但是点击又必须跳转到另外一张图,往往会最后跳转到目标网址,可以在onclick事件函数中加入ruturn false,阻止跳转到页面. ...

  5. Linux less命令语法

    一.Linux less命令语法 less [参数] 文件 less命令非常强大,在此只介绍几个常用的参数,更多参数使用man less来查看Linux帮助手册. -b <缓冲区大小> 设 ...

  6. phpcmsv9 同时调用多个栏目的文章标签

    V9版本默认好像没有多栏目调用的标签,例如我用{pc:content action="lists" catid ="6,7,8,9,10" num=" ...

  7. 阻塞 , 非阻塞 , 同步 ,异步 , I/O模型

    •阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否需要等待: •同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞:异步只需要I/O操作完成的通知,并不主动读写 ...

  8. VS05错误:部署WEB文件失败

    直接生成一个空项目就不存在这个问题了.

  9. docker使用记录

    1.安装(开始前要注意系统内核版本是否合适,建议用7以上的系统吧,少点坑) //安装docker yum -y install docker-io //启动 service docker start ...

  10. ErrorUnable to tunnel through proxy. Proxy returns HTTP1.1 400 Bad Reques

    导入项目的时候,一般会出现这种错误,因为我们的gradle版本,不对,所以默认AS导入后,回去下载你需要的gradle,所以很慢, 先打开:项目路径底下的\gradle\wrapper\gradle- ...