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 ...
随机推荐
- 软工1816 · Alpha冲刺(4/10)
团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 完成菜品信息的标定.量化以及整理成csv的任务 接下来的计划 & ...
- qwe
这次作业我负责的部分是把爬取完的聊天记录经行数据挖掘以及经行各种普通过滤高级过滤等. 运行截图如下: 数据分为四部分:账户名.qq/邮箱.包含关键词的发言次数.包含关键词的发言字数. 遇到的困难及解决 ...
- 从零讲JAVA ,给你一条 清晰地学习道路!该学什么就学什么!!
1.计算机基础: 1.1数据机构基础: 主要学习:1.向量,链表,栈,队列和堆,词典.熟悉2.树,二叉搜索树.熟悉3.图,有向图,无向图,基本概念4.二叉搜索A,B,C类熟练,9大排序熟悉.5.树的前 ...
- python学习笔记08:安装django
linux环境安装django: sudo pip install django windows环境安装django: pip install django 验证django是否安装: python ...
- 《学习OpenCV》课后习题解答1
题目:(P104) 下面这个练习是帮助掌握矩阵类型.创造一个三通道二维矩阵,字节类型,大小为100*100,并设置所有数值为0. a.在矩阵中使用cvCircle( CvArr* img, CvPoi ...
- PHP获取网页内容的几种方法
方法1: 用file_get_contents以get方式获取内容 <?php $url='http://www.domain.com/?para=123'; $html= file_get_c ...
- centos7编译安装redis遇坑
编译redis时:make cc Command not found 原因分析:没有安装gcc,执行: yum install gcc 编译redis时:error: jemalloc/jemallo ...
- TCP协议详解7层和4层解析(美团,阿里) 尤其是三次握手,四次挥手 具体发送的报文和状态都要掌握
如果想了解HTTP的协议结构,原理,post,get的区别(阿里面试题目),请参考:HTTP协议 结构,get post 区别(阿里面试) 这里有个大白话的解说,可以参考:TCP/IP协议三次握手和四 ...
- asp.net MVC 导出查询结果到Excel
首先在View视图中有一表单form,导出按钮<input class="btn export" type="button" value="导出 ...
- asp.net中缓存的使用
刚学到asp.net怎么缓存,这里推荐学习一下 www.cnblogs.com/wang726zq/archive/2012/09/06/cache.html http://blog.csdn.net ...