两双手

两双手

    老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式。
    老W下棋时觉得无聊,便决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从 ( u , v ) (u,v) (u,v) 移动到 ( u + B x , v + B y ) (u+Bx,v+By) (u+Bx,v+By) 而另一双手能让 马从 ( u , v ) (u,v) (u,v)移动到 ( u + A x , v + A y ) (u+Ax,v+Ay) (u+Ax,v+Ay)
    小W看见老W的下棋方式,觉得非常有趣,他开始思考一个问题:假设棋盘是个无限大的二维平面,一开始马在原点 ( 0 , 0 ) (0,0) (0,0)上,若用老W的两种方式进行移动,他有多少种不同的移动方法到达点 ( E x , E y ) (Ex,Ey) (Ex,Ey)呢?两种移动方法不同当且仅当移动步数不同或某一步所到达的点不同。
    老W听了这个问题,觉得还不够有趣,他在平面上又设立了n个禁止点,表示马不能走到这些点上,现在他们想知道,这种情况下马有多少种不同的移动方法呢?答案数可能很大,你只要告诉他们答案模 ( 1 0 9 + 7 ) (10^9+7) (109+7)的值就行。

大佬博客传送门(这个讲的比较清楚)
虽然上述的做法跟我的是不太一样的,但是如果你能看懂一半,再回来看我的您就看得懂了。
    分析思路:
    如果我们不考虑禁止点,那么我们可以得到一个二元一次方程,就 u + a ∗ A x + b ∗ B x = E x u+a*Ax+b*Bx=Ex u+aAx+bBx=Ex v + a ∗ A y + b ∗ B y = E y v+a*Ay+b*By=Ey v+aAy+bBy=Ey。因为出发点是 ( 0 , 0 ) (0,0) (0,0)。所以我们可以得到一个唯一解
     a = ( E x ∗ B y − E y ∗ B x ) / ( B y ∗ A x − B x ∗ A y ) a=(Ex*By-Ey*Bx)/(By*Ax-Bx*Ay) a=(ExByEyBx)/(ByAxBxAy)
     b = ( E y ∗ A x − E x ∗ A y ) / ( B y ∗ A x − B x ∗ A y ) b=(Ey*Ax-Ex*Ay)/(By*Ax-Bx*Ay) b=(EyAxExAy)/(ByAxBxAy)
    如果a,b其中有一个<0或者是小数都不能算为能到达的点呢
    那么方案数是多少呢?这里运用下组合数,就是 ( a a + b ) \tbinom{a}{a+b} (a+ba)。相当于我们总共有a+b次操作,选择Ax,Ay作为首次移动方式的情况有a种。
    那么我们现在来考虑禁止点。如果路上只有一个禁止点,那么我们只需要减去经过那个禁止点到达终点的路径数就可以了。设数组 c [ i ] [ j ] c[i][j] c[i][j]表示从i号节点到j号节点的方案数。那么我们只有一个禁止点的情况就是 c [ 0 ] [ v ] ∗ c [ v ] [ n ] c[0][v]*c[v][n] c[0][v]c[v][n]。如果是两个点呢?我同样也可以用这样的方法表示,但是我们这样会减多了(简单的容斥原理)。我们不妨先以a 为关键字,b为第二关键字,由小到大排序。重新转化问题。我们将a看成向右移动,b看成向上移动。以这样的方式我们会得到新的图,新的点坐标。计算方式依旧不变,但是这就方便了我们容斥。排在后面的点,一般来说是能通过前面转移得到的(有特殊情况,比如a很大,b很小的那种)。我们设 f [ i ] f[i] f[i]表示从起点到i号点路上不经过任何一个禁止点的路径数。初值赋值为 c [ a i + b i ] [ a i ] c[a_i+b_i][a_i] c[ai+bi][ai]容斥一下: f [ i ] − = c [ a i − a j + b i − b j ] [ a i − a j ] f[i]-=c[a_i-a_j+b_i-b_j][a_i-a_j] f[i]=c[aiaj+bibj][aiaj]注意这里需要保证 b i > = b j b_i>=b_j bi>=bj
最后输出答案 f [ n ] f[n] f[n]即可。
    需要注意的是,组合数的处理要用阶层处理,阶层预处理的时候要处理到1000000才行。
    代码的话····A了再说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值