BZOJ #4767. 两双手
题面传送门
首先我们设走到终点走了步第一种走法,步第二种走法,则可得方程组:
解得
所以我们可以得出起点到任意点的步数。如果不能整除到终点先特判掉。
然后就变成一个坐标系走路问题:你要走横向步,纵向步,且不能经过个形如的障碍点,问你方案数。
看上去可以直接设表示走到第步,走了步横向的方案数,但是这样复杂度达到不可取。考虑容斥,先将障碍点按照横纵坐标升序排序,然后设表示第个障碍点,已经选了个障碍点的方案数,两个障碍点之间的转移可以用组合意义求解,最后统计答案即可,时间复杂度,进一步的,因为容斥系数为,可以看作选了一个就将贡献乘上,因此可以将后一维省去,时间复杂度降至。
所以题目只给500的原因是要预处理范围内的阶乘逆元
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define ll long long
#define db double
#define lb long db
#define N (500+5)
#define M ((N<<5)+5)
#define K (350)
#define mod 1000000007
#define Mod (mod-1)
#define eps (1e-9)
#define ull unsigned ll
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((k+1)*(x)+(y))
#define R(n) (1ll*rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using namespace std;
int n,m,k,x,y,z,Ex,Ey,E,Px,Py,H,Ax,Ay,Bx,By,X[N],Y[N];ll dp[N],Ans,frc[N*N*4],Inv[N*N*4];
struct Node{int x,y;}S[N];I bool cmp(Node x,Node y){return x.x^y.x?x.x<y.x:x.y<y.y;}
I ll mpow(ll x,int y=mod-2){ll Ans=1;while(y) y&1&&(Ans=Ans*x%mod),y>>=1,x=x*x%mod;return Ans;}
I ll C(int x,int y){return frc[x+y]*Inv[y]%mod*Inv[x]%mod;}
int main(){
freopen("1.in","r",stdin);
int i,j,h;scanf("%d%d%d",&Ex,&Ey,&n);scanf("%d%d%d%d",&Ax,&Ay,&Bx,&By);for(i=1;i<=n;i++) scanf("%d%d",&X[i],&Y[i]);for(frc[0]=Inv[0]=i=1;i<=1000000;i++) frc[i]=frc[i-1]*i%mod;Inv[1000000]=mpow(frc[1000000]);for(i=999999;~i;i--) Inv[i]=Inv[i+1]*(i+1)%mod;
E=Ay*Bx-Ax*By;if((Ey*Bx-Ex*By)%E||(Ey*Ax-Ex*Ay)%E) {puts("0");return 0;}for(i=1;i<=n;i++){if((Y[i]*Bx-X[i]*By)%E||(Y[i]*Ax-X[i]*Ay)%E) continue;S[++H]=(Node){(Y[i]*Bx-X[i]*By)/E,-(Y[i]*Ax-X[i]*Ay)/E};}
Px=(Ey*Bx-Ex*By)/E;Py=-(Ey*Ax-Ex*Ay)/E;sort(S+1,S+H+1,cmp);dp[0]=1;for(i=0;i<=H;i++){
for(j=0;j<i;j++){if(S[j].x>S[i].x||S[j].y>S[i].y) continue;dp[i]-=dp[j]*C(S[i].x-S[j].x,S[i].y-S[j].y)%mod;}dp[i]=(dp[i]%mod+mod)%mod;S[i].x<=Px&&S[i].y<=Py&&(Ans+=dp[i]*C(Px-S[i].x,Py-S[i].y)%mod);
}printf("%lld\n",Ans%mod);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2021-07-04 luogu P4725 【模板】多项式对数函数(多项式 ln)
2021-07-04 luogu P5205 【模板】多项式开根