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的方案
由于坐标化简后相当于只向右上走,所以按坐标排序,只有排在它之前的点可能到达它

  1. /*
  2. 代码wa了没调出来。
  3. */
  4. #include<cstdio>
  5. #include<iostream>
  6. #include<algorithm>
  7. #include<cstring>
  8. #define ll long long
  9. #define N 505
  10. #define mod 1000000007
  11. using namespace std;
  12. int ex,ey,ax,ay,bx,by,cnt,n,m,num,fac[1005*1005],f[N];
  13. struct node{int x,y;}p[N];
  14. bool check(int x,int y,int &a,int &b){
  15. int t1=x*by-y*bx,t2=ax*by-ay*bx;
  16. if(t1%t2)return 0;
  17. a=t1/t2;
  18. t1=x*ay-y*ax;t2=-t2;
  19. if(t1%t2)return 0;
  20. b=t1/t2;return 1;
  21. }
  22. void pre(){
  23. fac[0]=1;
  24. for(int i=1;i<=1e6;i++)fac[i]=(1ll*fac[i-1]*i)%mod;
  25. }
  26. int quick(int a,int b){
  27. int c=1;
  28. while(b){
  29. if(b&1)c=(1ll*c*a)%mod;
  30. a=(1ll*a*a)%mod;b>>=1;
  31. }
  32. return c;
  33. }
  34. int C(int x,int y){
  35. int ans=fac[x];
  36. int d1=quick(fac[y],mod-2);
  37. int d2=quick(fac[x-y],mod-2);
  38. ans=(1ll*ans*d1)%mod;
  39. ans=(1ll*ans*d2)%mod;
  40. return ans;
  41. }
  42. int calc(int x,int y){
  43. if(x<0||y<0)return 0;
  44. return C(x+y,y);
  45. }
  46. bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;}
  47. int main(){
  48. #ifdef wsy
  49. freopen("data.in","r",stdin);
  50. #else
  51. //freopen(".in","r",stdin);
  52. //freopen(".out","w",stdout);
  53. #endif
  54. int A,B;
  55. scanf("%d%d%d",&ex,&ey,&num);
  56. scanf("%d%d%d%d",&ax,&ay,&bx,&by);
  57. if(!check(ex,ey,n,m)){puts("0");return 0;}
  58. for(int i=1;i<=num;i++){
  59. int a,b;scanf("%d%d",&a,&b);
  60. if(check(a,b,A,B)&&A>=1&&A<=n&&B>=1&&B<=m)
  61. p[++cnt].x=A;p[cnt].y=B;
  62. }
  63. pre();
  64. p[++cnt].x=n;p[cnt].y=m;
  65. sort(p+1,p+1+cnt,cmp);
  66. for(int i=1;i<=cnt;i++){
  67. f[i]=calc(p[i].x,p[i].y);
  68. for(int j=1;j<i;j++)
  69. f[i]=(f[i]-(ll)f[j]*calc(p[i].x-p[j].x,p[i].y-p[j].y))%mod;
  70. }
  71. f[cnt]<0?f[cnt]+=mod:1;
  72. cout<<f[cnt];
  73. return 0;
  74. }

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. 从Nest到Nesk -- 模块化Node框架的实践

    文: 达孚(沪江Web前端架构师) 本文原创,转至沪江技术 首先上一下项目地址(:>): Nest:https://github.com/nestjs/nest Nesk:https://git ...

  2. 不允许用(a+b)/2这种方式求两个数的均值;如下程序在Linux和32位集成开发环境中运行

    #define MAX(a,b) ((a)>(b)?(a):(b)) #include<stdio.h> int main() { int a = 10; int b = 20; i ...

  3. 帧动画的创建方式 - xml方式

    废话不多说,先看东西   创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画:   本文内容主要关注 xml文件 创建帧动画的方式   xml文件 ...

  4. RTSP连接中断重连的问题

    最近在调查的一个问题. 起因是我司的一款数据链产品,15km数字图传,测试时发现视频画面经常会出现马赛克或卡顿. 图传设置了10Mbps速率,而视频码流是4Mbps,按道理不应该出现这种问题. 经过几 ...

  5. isinstance(obj1,class) 可以判断前者是否是后者的实例

    isinstance(obj1,class) 可以判断前者是否是后者的实例

  6. jacascript DOM节点——节点获取与选择器API

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! DOM 操作必须等待 HTML 加载完毕之后,才可以获取节点:有两种方法: 把 script 标签放到代码 ...

  7. EF5中 执行 sql语句使用Database.ExecuteSqlCommand 返回影响的行数 ; EF5执行sql查询语句 Database.SqlQuery 带返回值

    一: 执行sql语句,返回受影响的行数 在mysql里面,如果没有影响,那么返回行数为  -1 ,sqlserver 里面  还没有测试过 using (var ctx = new MyDbConte ...

  8. django 开发忘记密码通过邮箱找回功能

    一.流程分析: 1.点击忘记密码====>forget.html页面,输入邮箱和验证码,发送验证链接网址的邮件====>发送成功,跳到send_success.html提示 2.到邮箱里找 ...

  9. 【SQL.基础构建-第一节(1/4)】

    --        Tips:数据库与sql--    一.What's 数据库-- 1.数据库(Database,DB):将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合.--   ...

  10. .NET Core Community 首个千星项目诞生:CAP

    项目简介 在我们构建 SOA 或者 微服务系统的过程中,我们通常需要使用事件来对各个服务进行集成,在这过程中简单的使用消息队列并不能保证数据的最终一致性, CAP 采用的是和当前数据库集成的本地消息表 ...