hdu 5852 :Intersection is not allowed! 行列式
Posted SD_le
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5852 :Intersection is not allowed! 行列式相关的知识,希望对你有一定的参考价值。
有K个棋子在一个大小为N×N的棋盘。一开始,它们都在棋盘的顶端,它们起始的位置是 (1,a1),(1,a2),...,(1,ak) ,它们的目的地是 (n,b1),(n,b2),...,(n,bk)。
一个位于 (r,c) 的棋子每一步只能向右走到 (r,c+1) 或者向下走到 (r+1,c) 。
我们把 i 棋子从 (1,ai) 走到 (n,bi) 的路径记作 pi 。
你的任务是计算有多少种方案把n个棋子送到目的地,并且对于任意两个不同的棋子 i,j ,使得路径 pi 与 pj 不相交(即没有公共点)。
容斥原理。
假设只有两个点,那么答案就是它们以任意路径到达终点的方案数减去相交的方案。
比如 a1->b1 ,a2->b2 ,那它们相交的方案就是 a1->b2,a2->b1的所有方案。
因为在最后一个交点下把两条路径换一下它们是一一对应的。
扩展到多个点时有$n!$种向下对应对应的方案,每个方案的容斥系数是$-1^{逆序对个数}$。
实际上这东西就是矩阵的行列式。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define ll long long 6 #define N 105 7 using namespace std; 8 int n,k; 9 const int inf = 200000; 10 const int p = 1000000007; 11 int jie[200005],ni[200005]; 12 void yu() 13 { 14 jie[0]=ni[0]=ni[1]=1; 15 for(int i=1;i<=inf;i++)jie[i]=1LL*i*jie[i-1]%p; 16 for(int i=2;i<=inf;i++)ni[i]=(1LL*(-p/i)*ni[p%i]%p+p)%p; 17 for(int i=1;i<=inf;i++)ni[i]=1LL*ni[i-1]*ni[i]%p; 18 } 19 int pw(ll x,int y) 20 { 21 ll lst=1; 22 while(y) 23 { 24 if(y&1)lst=lst*x%p; 25 y>>=1; 26 x=1LL*x*x%p; 27 } 28 return (int)lst; 29 } 30 int c(int n,int m) 31 { 32 return 1LL*jie[n]*ni[m]%p*ni[n-m]%p; 33 } 34 int st[N],ed[N]; 35 ll a[N][N]; 36 void guess() 37 { 38 ll ans=1; 39 for(int i=1;i<=k;i++) 40 { 41 for(int j=i;j<=k;j++) 42 { 43 if(a[j][i]) 44 { 45 if(j!=i)ans*=-1; 46 for(int l=1;l<=k;l++)swap(a[i][l],a[j][l]); 47 break; 48 } 49 } 50 ll tp=pw(a[i][i],p-2); 51 for(int j=i+1;j<=k;j++) 52 { 53 if(a[j][i]) 54 { 55 ll tmp=p-tp*a[j][i]%p; 56 for(int l=i;l<=k;l++) 57 { 58 a[j][l]=(a[j][l]+tmp*a[i][l]%p)%p; 59 } 60 } 61 } 62 } 63 if(ans==-1)ans=p-1; 64 for(int i=1;i<=k;i++)ans=ans*a[i][i]%p; 65 printf("%lld\n",ans); 66 return ; 67 } 68 int main() 69 { 70 yu(); 71 scanf("%d%d",&n,&k); 72 for(int i=1;i<=k;i++)scanf("%d",&st[i]); 73 for(int i=1;i<=k;i++)scanf("%d",&ed[i]); 74 for(int i=1;i<=k;i++) 75 { 76 for(int j=1;j<=k;j++) 77 { 78 if(ed[j]>=st[i])a[i][j]=c(n-1+abs(ed[j]-st[i]),n-1); 79 } 80 } 81 guess(); 82 return 0; 83 }
以上是关于hdu 5852 :Intersection is not allowed! 行列式的主要内容,如果未能解决你的问题,请参考以下文章