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 }
时间: 2024-08-06 11:57:21

hdu 5852 :Intersection is not allowed! 行列式的相关文章

hdu 5120 Intersection 圆环面积交

Intersection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5120 Description Matt is a big fan of logo design. Recently he falls in love with logo made up by rings. The following figures are some famous examples

hdu 5120 Intersection

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5120 A ring is a 2-D figure bounded by two circles sharing the common center. The radius for these circles are denoted by r and R (r < R). For more details, refer to the gray part in the illustration bel

hdu 5120 - Intersection(解题报告)

Intersection Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 1036    Accepted Submission(s): 407 Problem Description Matt is a big fan of logo design. Recently he falls in love with logo made

HDU 5120 Intersection(圆的面积交)

题目大意:给你两个圆环,让你求出来圆环的面积交,需要用到圆的面积交,然后容斥一下,就可以得到圆环的面积交.画一下图就会很清晰. Intersection Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 526    Accepted Submission(s): 226 Problem Description Matt is a b

HDU 5120 Intersection(2014北京赛区现场赛I题 计算几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5120 解题报告:给你两个完全相同的圆环,要你求这两个圆环相交的部分面积是多少? 题意看了好久没懂.圆环由一个大圆里面套一个小圆,中间部分就是圆环,两圆环相交面积 = 大圆相交的面积 - 2*大圆与小圆相交的面积 + 小圆与小圆相交的面积. 也就是说,这题就可以化为求两个圆的相交的面积了.可以利用两个圆的方程,求出圆的交点所在的直线,然后求出圆心到这条直线的距离,就可以求出两个圆对应的扇形的圆心角是多

Intersection is not allowed!

给出n∗n网格,顶部有k个起点,底部有k个相对应的终点每次只能向下或向右走求有多少种从各个起点出发到达对应终点且路径不相交的路径?(对109+7取模) n*m空间从左上角走到右下角只走右或者下的方案数位C(n,n+m) 首先考虑两个棋子的情况,即一个棋子从a1到b1,另一个棋子从a2到b2,不考虑交叉方案数显然是C(b1-a1+n-1,n-1) * C(b2-a2+n-1,n-1) 对于路径交叉的方案,对于一个a1->b2,a2->b1的方案,这两条路径必然会相交, 把最后一个交叉点之后的两条

HDU 5120 Intersection(几何模板题)

题意:给定两个圆环,求两个圆环相交的面积. 思路:由于圆心和半径不一样,分了好多种情况,后来发现只要把两个圆相交的函数写好之后就不需要那么复杂了.两个圆相交的面积的模板如下: double area_of_overlap(point c1, double r1, point c2, double r2) { double d = dist(c1, c2); if (sgn(d - r1 - r2) >= 0) return 0; if (sgn(fabs(r1 - r2) - d) >= 0)

HDU 5120 Intersection (求圆环相交面积)

题意:给定圆环的内径r和外径R,以及2个相同圆环的圆心,求两个圆环的相交面积. 思路: S = A大B大 - A大B小 - A小B大 + A小B小.(A表示A环,大表示大圆,B同) 1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include

Lindstr&#246;m–Gessel–Viennot lemma定理 行列式板子

https://blog.csdn.net/qq_37025443/article/details/86537261 博客 下面是wiki上的讲解,建议耐心地看一遍...虽然看了可能还是不懂 https://en.wikipedia.org/wiki/Lindström–Gessel–Viennot_lemma Lindström–Gessel–Viennot lemma定理是 起点集合A=(a1,a2,a3..an),终点集合B=(b1.b2,b3,..bn) 假定P是从一条从一个点到另一个点