4767: 两双手

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 684  Solved: 208
[Submit][Status][Discuss]

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)的值就行。

Input

第一行三个整数Ex,Ey,n分别表示马的目标点坐标与禁止点数目。

第二行四个整数Ax,Ay,Bx,By分别表示两种单步移动的方法,保证Ax*By-Ay*Bx≠0

接下来n行每行两个整数Sxi,Syi,表示一个禁止点。

|Ax|,|Ay|,|Bx|,|By| <= 500, 0 <= n,Ex,Ey <= 500

Output

仅一行一个整数,表示所求的答案。

Sample Input

4 4 1
0 1 1 0
2 3

Sample Output

40

组合+容斥
可以发现两种方法走的步数是一定的
因为 AX*x+BX*y=ex AY*x+BY*y=ey唯一解
特判能不能走到此点,并且把坐标化成二元一次方程组的解(x,y)
那么ans=总方案-路上经过禁止点的方案

算路径方案用组合数
(0,0)一次向上或右走一单位,走到(n,m)的方案为C(n+m,m)

再考虑路上经过禁止点的方案
对于每个禁止点,可以算出到达它的方案,再用容斥减去之前已经经过禁止点的方案
对于禁止点i,如果禁止点j可以到达i,那么到达i的方案要减去到达j再到i的方案
由于坐标化简后相当于只向右上走,所以按坐标排序,只有排在它之前的点可能到达它

/*
代码wa了没调出来。
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
#define N 505
#define mod 1000000007
using namespace std;
int ex,ey,ax,ay,bx,by,cnt,n,m,num,fac[1005*1005],f[N];
struct node{int x,y;}p[N];
bool check(int x,int y,int &a,int &b){
int t1=x*by-y*bx,t2=ax*by-ay*bx;
if(t1%t2)return 0;
a=t1/t2;
t1=x*ay-y*ax;t2=-t2;
if(t1%t2)return 0;
b=t1/t2;return 1;
}
void pre(){
fac[0]=1;
for(int i=1;i<=1e6;i++)fac[i]=(1ll*fac[i-1]*i)%mod;
}
int quick(int a,int b){
int c=1;
while(b){
if(b&1)c=(1ll*c*a)%mod;
a=(1ll*a*a)%mod;b>>=1;
}
return c;
}
int C(int x,int y){
int ans=fac[x];
int d1=quick(fac[y],mod-2);
int d2=quick(fac[x-y],mod-2);
ans=(1ll*ans*d1)%mod;
ans=(1ll*ans*d2)%mod;
return ans;
}
int calc(int x,int y){
if(x<0||y<0)return 0;
return C(x+y,y);
}
bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;}
int main(){
#ifdef wsy
freopen("data.in","r",stdin);
#else
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
#endif
int A,B;
scanf("%d%d%d",&ex,&ey,&num);
scanf("%d%d%d%d",&ax,&ay,&bx,&by);
if(!check(ex,ey,n,m)){puts("0");return 0;}
for(int i=1;i<=num;i++){
int a,b;scanf("%d%d",&a,&b);
if(check(a,b,A,B)&&A>=1&&A<=n&&B>=1&&B<=m)
p[++cnt].x=A;p[cnt].y=B;
}
pre();
p[++cnt].x=n;p[cnt].y=m;
sort(p+1,p+1+cnt,cmp);
for(int i=1;i<=cnt;i++){
f[i]=calc(p[i].x,p[i].y);
for(int j=1;j<i;j++)
f[i]=(f[i]-(ll)f[j]*calc(p[i].x-p[j].x,p[i].y-p[j].y))%mod;
}
f[cnt]<0?f[cnt]+=mod:1;
cout<<f[cnt];
return 0;
}

bzoj4767两双手 容斥+组合的更多相关文章

  1. 2019.02.11 bzoj4767: 两双手(组合数学+容斥dp)

    传送门 题意简述:你要从(0,0)(0,0)(0,0)走到(ex,ey)(ex,ey)(ex,ey),每次可以从(x,y)(x,y)(x,y)走到(x+ax,y+ay)(x+ax,y+ay)(x+ax ...

  2. BZOJ4767: 两双手【组合数学+容斥原理】

    Description 老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式.老W下棋时觉得无聊,便决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v) ...

  3. BZOJ4767 两双手

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  4. BZOJ4767 两双手(组合数学+容斥原理)

    因为保证了两向量不共线,平面内任何一个向量都被这两个向量唯一表示.问题变为一张有障碍点的网格图由左上走到右下的方案数. 到达终点所需步数显然是平方级别的,没法直接递推.注意到障碍点数量很少,那么考虑容 ...

  5. bzoj4487[Jsoi2015]染色问题 容斥+组合

    4487: [Jsoi2015]染色问题 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 211  Solved: 127[Submit][Status ...

  6. bzoj2839: 集合计数 容斥+组合

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 523  Solved: 287[Submit][Status][Discuss] ...

  7. LOJ.6160.[美团CodeM初赛 RoundA]二分图染色(容斥 组合)

    题目链接 \(Description\) 求在\(2n\)个点的完全二分图(两边各有\(n\)个点)上确定两组匹配,使得两个匹配没有交集的方案数. \(n\leq10^7\). \(Solution\ ...

  8. bzoj2839 集合计数(容斥+组合)

    集合计数 内存限制:128 MiB 时间限制:1000 ms 标准输入输出     题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 ...

  9. BZOJ 3294: [Cqoi2011]放棋子 计数 + 容斥 + 组合

    比较头疼的计数题. 我们发现,放置一个棋子会使得该棋子所在的1个行和1个列都只能放同种棋子. 定义状态 $f_{i,j,k}$ 表示目前已使用了 $i$ 个行,$j$ 个列,并放置了前 $k$ 种棋子 ...

随机推荐

  1. 浅谈数据结构vector

    vector: 又名 向量 1.C++中的一种数据结构. 2.是一个类. 3.相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. A.使用时, ...

  2. mycat入门_介绍与安装

    利用闲暇时间接触了下mycat. 一.介绍 1.概述: 国内最活跃的.性能最好的开源数据库中间件,可以理解为数据库和应用层之间的一个代理组件. 2.作用: 读写分离.分表分库.主从切换. 3.原理: ...

  3. 双击CAD对象(具有扩展数据),显示自定义对话框实现方法

    转自:Cad人生 链接:http://www.cnblogs.com/cadlife/p/3463337.html 题目:双击CAD对象,显示自定义对话框实现方法 内容粘贴如下: 主要是绑定两个事件: ...

  4. Linux - IDA - 安装 ( 带F5功能 )

    Linux - IDA - 安装 ( 带F5功能 ) 0x00 前言 最近在熟悉deepin系统,想着把逆向的一些软件也迁移过去,但像ida,Ollydbg这些工具一般都是在windows下使用,所以 ...

  5. React 深入系列2:组件分类

    文:徐超,<React进阶之路>作者 授权发布,转载请注明作者及出处 React 深入系列2:组件分类 React 深入系列,深入讲解了React中的重点概念.特性和模式等,旨在帮助大家加 ...

  6. Python内置函数(64)——classmethod

    英文文档: classmethod(function) Return a class method for function. A class method receives the class as ...

  7. Python内置函数(7)——sum

    英文文档: sum(iterable[, start]) Sums start and the items of an iterable from left to right and returns ...

  8. tensorflow安装篇

    安装虚拟机redhat7u4-64 镜像文件在http://www.linuxfly.org/post/659 更换yum 参考https://blog.csdn.net/xiaoyiaoyou/ar ...

  9. .NET CORE 框架ABP的代码生成器(ABP Code Power Tools )使用说明文档

    前言 各位好,又是一个多月没更新文章了. 原因嘛,大家都懂的,太忙了~ 临近年末,公司的项目.年会的做技术支持,同事朋友聚餐也比较频繁. 当然视频教程也没有继续更新.我的锅~ 但是这个月好歹抽空做了一 ...

  10. HTML mate标签

    META标签分两大部分:HTTP标题信息(http-equiv)和页面描述信息(name). http-equiv http-equiv类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正 ...