BZOJ 4767 兩雙手(組合數學 Dp)

2022-05-16 04:16:33 字數 1371 閱讀 4248

description

老w是個棋藝高超的棋手,他最喜歡的棋子是馬,更具體地,他更加喜歡馬所行走的方式。老w下棋時覺得無聊,便

決定加強馬所行走的方式,更具體地,他有兩雙手,其中一雙手能讓馬從(u,v)移動到(u+ax,v+ay)而另一雙手能讓

馬從(u,v)移動到(u+bx,v+by)。小w看見老w的下棋方式,覺得非常有趣,他開始思考乙個問題:假設棋盤是個無限

大的二維平面,一開始馬在原點(0,0)上,若用老w的兩種方式進行移動,他有多少種不同的移動方法到達點(ex,ey

)呢?兩種移動方法不同當且僅當移動步數不同或某一步所到達的點不同。老w聽了這個問題,覺得還不夠有趣,他

在平面上又設立了n個禁止點,表示馬不能走到這些點上,現在他們想知道,這種情況下馬有多少種不同的移動方

法呢?答案數可能很大,你只要告訴他們答案模(10^9+7)的值就行。

solution

ax*by-ay*bx≠0所以向量a、b的步數是固定的,走法也就有c(m+n,m)種

先對障礙點排序

dp,f[i]表示到達障礙點i且不經過其他障礙點的方案數(用容斥減去經過其他障礙點的方案數)

#include#include

#include

#include

#include

#define mod 1000000007

#define maxn 500005typedef

long

long

ll;using

namespace

std;

intn,ax,ay,bx,by;

ll fac[maxn],inv[maxn],f[maxn];

struct

node

p[maxn];

void

init()

ll c(ll x,ll y)

bool

cmp(node a,node b)

void calc(int &x,int &y)

n=(ay*x-ax*y)/(bx*ay-ax*by);

if((by*x-bx*y)%(ax*by-bx*ay))

m=(by*x-bx*y)/(ax*by-bx*ay);

x=m,y=n;

}int

main()

sort(p+1,p+1+n,cmp);

p[n+1]=p[0

];

for(int i=1;i<=n+1;i++)

printf(

"%lld\n

",f[n+1

]);

return0;

}

bzoj4767兩雙手 容斥 組合

4767 兩雙手time limit 10 sec memory limit 256 mb submit 684 solved 208 submit status discuss description 老w是個棋藝高超的棋手,他最喜歡的棋子是馬,更具體地,他更加喜歡馬所行走的方式。老w下棋時覺得無...

BZOJ 4767 兩雙手(容斥 DP)

4767.兩雙手 題目位址 3782.上學路線 題目位址 一道很像的題。將兩個行走方式看做兩個二維向量 vec,vec 令其為該向量空間的基,對該空間變換後,得到每個禁止點的新座標和終點的新座標。可以發現從乙個點 u u 1,u 2 走到另外乙個點 v v 1,v 2 的行走步數是唯一的 由於基向量...

省選專練之容斥 BZOJ4767 兩雙手

老w是個棋藝高超的棋手,他最喜歡的棋子是馬,更具體地,他更加喜歡馬所行走的方式。老w下棋時覺得無聊,便決定加強馬所行走的方式,更具體地,他有兩雙手,其中一雙手能讓馬從 u,v 移動到 u ax,v ay 而另一雙手能讓馬從 u,v 移動到 u bx,v by 小w看見老w的下棋方式,覺得非常有趣,他...