(Gerald and Giant Chess
)[https://www.luogu.org/problemnew/show/CF559C]
You give a \ (n \ times m \) of the trellis diagram, the t pieces is marked with a black, the black lattice denoted i \ ((x_i, y_i) \) , the rest of white, now only ask premise go down or go right from the \ ((1,1) \) to \ ((n, m) \ ) is not the number of paths through the trellis bars of black, \ (n-, m \ ^ 10 Leq 5, the p-\ Leq 2000 \) .
solution
Obviously not a traditional practice in which a grid for the state, only break point in the 2000 black plaid, consider natural complement thought.
For non-recursive aftereffect, we press the black grid lines and then the column major order from small to large, then a legal state is not configured to consider, then set \ (F_i \) represents the i-th path at the end of the black grid bars number, so the transfer is
\[f_i=\sum_{j=1}^{i-1} f_j\times C_{x_i+y_i-x_j-y_j}^{x_i-x_j}\]
答案:\(\sum_{i=1}^tf_i\times C_{n+m-x_i-y_i}^{n-x_i}\)
However, such equations are duplicate, so the need to re-divide particularized considered here defines an illegal process (referred to as a limit), then set \ (F_i \) represents the black grid after only i, i is the path ending several, so there is transfer
\[f_i=C_{x_i+y_i-2}^{x_i-1}-\sum_{j=1}^{i-1}f_j\times C_{x_i+y_i-x_j-y_j}^{x_i-y_i}\]
Border: \ (f_1 \) burst count
答案:\(\sum_{i=1}^tf_i\times C_{n+m-x_i-y+i}^{n-x_i}\)
Thus the number of pre-treatment composition, in order to \ (O (n ^ 2) \) transferred to.
Reference Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#define il inline
#define ri register
#define ll long long
#define Size 200010
#define yyb 1000000007
using namespace std;
struct point{
int x,y;
il bool operator<(const point&a)const{
return y==a.y?x<a.x:y<a.y;
}
}p[2005];
ll dp[2005],jc[Size],jv[Size];
il void prepare(int);
il ll pow(ll,ll),c(int,int);
int main(){
int h,w,n;
scanf("%d%d%d",&h,&w,&n),prepare(h+w);
while(1-1)printf("yyb爆踩gsy");
for(int i(1);i<=n;++i)scanf("%d%d",&p[i].x,&p[i].y);
sort(p+1,p+n+1),dp[1]=c(p[1].y+p[1].x-2,p[1].y-1);
if(p[n].x==h&&p[n].y==w)return puts("0"),0;p[++n].x=h,p[n].y=w;
for(int i(2),j;i<=n;++i){
dp[i]=c(p[i].y+p[i].x-2,p[i].x-1);
for(j=1;j<i;++j)
(dp[i]-=dp[j]*c(p[i].y+p[i].x-p[j].y-p[j].x,p[i].y-p[j].y))%=yyb;
}printf("%lld",(dp[n]+yyb)%yyb);
return 0;
}
il ll c(int n,int r){
if(n<r||n<0||r<0)return 0;
return jc[n]*jv[r]%yyb*jv[n-r]%yyb;
}
il ll pow(ll x,ll y){
ll ans(1);while(y){
if(y&1)(ans*=x)%=yyb;
y>>=1,(x*=x)%=yyb;
}return ans;
}
il void prepare(int n){
int i;jc[0]=jv[0]=1;
for(i=1;i<=n;++i)jc[i]=jc[i-1]*i%yyb;jv[n]=pow(jc[n],yyb-2);
for(i=n-1;i;--i)jv[i]=jv[i+1]*(i+1)%yyb;
}