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. 在linux中关闭防火墙

    1) 重启后生效 开启: chkconfig iptables on 关闭: chkconfig iptables off 2) 即时生效,重启后失效 开启: service iptables sta ...

  2. 使用caffe训练mnist数据集 - caffe教程实战(一)

    个人认为学习一个陌生的框架,最好从例子开始,所以我们也从一个例子开始. 学习本教程之前,你需要首先对卷积神经网络算法原理有些了解,而且安装好了caffe 卷积神经网络原理参考:http://cs231 ...

  3. Android 扩大 View 的点击区域

    有时候,按照视觉图做出来效果后,发现点击区域过小,不好点击,用户体验肯定不好.扩大视图,就会导致整个视觉图变得不好看.那么有没有什么办法在不改变视图大小的前提下扩大点击区域呢? 答案是有! 能够解决这 ...

  4. 新概念英语(1-103)The French Test

    Lesson 103 The French test 法语考试 Listen to the tape then answer this question. How long did the exam ...

  5. SpringCloud的应用发布(三)vmvare+linux,xftp,xshell连接linux失败

    Vmvare内的linux虚拟机已经启动,但是 xftp和xshell连接不上? 环境信息:子网 192.168.136.* linux ip:192.168.136.100 一.核对linux的ip ...

  6. Spring Security入门(3-3)Spring Security 手工配置并注入 authenticationProvider 和 异常信息传递

    特别注意的是 这样就能保证抛出UsernameNotFoundException时,前台显示出错信息: 另外,ps:

  7. 自己造轮子系列之OOM框架AutoMapper

    [前言] OOM框架想必大家在Web开发中是使用频率非常之高的,如果还不甚了解OOM框架,那么我们对OOM框架稍作讲解. OOM顾名思义,Object-Object-Mapping实体间相互转换.常见 ...

  8. Python/MySQL(二、表操作以及连接)

    Python/MySQL(二.表操作以及连接) mysql表操作: 主键:一个表只能有一个主键.主键可以由多列组成. 外键 :可以进行联合外键,操作. mysql> create table y ...

  9. highstaock+websocket实现动态展现

    效果:从后台获取回测数据,在前端动态展现,和聚宽实现的回测效果相仿 大体思路:先传一个[[int,0],[int,0],[int,0],[int,0],[int,0],...]格式的死数据到前端渲染x ...

  10. 南阳OJ-91-阶乘之和---二进制枚举(入门)

    题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=91 题目大意: 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为 ...