bzoj4767两双手 容斥+组合
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两双手 容斥+组合的更多相关文章
- 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 ...
- BZOJ4767: 两双手【组合数学+容斥原理】
Description 老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式.老W下棋时觉得无聊,便决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v) ...
- BZOJ4767 两双手
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ4767 两双手(组合数学+容斥原理)
因为保证了两向量不共线,平面内任何一个向量都被这两个向量唯一表示.问题变为一张有障碍点的网格图由左上走到右下的方案数. 到达终点所需步数显然是平方级别的,没法直接递推.注意到障碍点数量很少,那么考虑容 ...
- bzoj4487[Jsoi2015]染色问题 容斥+组合
4487: [Jsoi2015]染色问题 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 211 Solved: 127[Submit][Status ...
- bzoj2839: 集合计数 容斥+组合
2839: 集合计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 523 Solved: 287[Submit][Status][Discuss] ...
- LOJ.6160.[美团CodeM初赛 RoundA]二分图染色(容斥 组合)
题目链接 \(Description\) 求在\(2n\)个点的完全二分图(两边各有\(n\)个点)上确定两组匹配,使得两个匹配没有交集的方案数. \(n\leq10^7\). \(Solution\ ...
- bzoj2839 集合计数(容斥+组合)
集合计数 内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 ...
- BZOJ 3294: [Cqoi2011]放棋子 计数 + 容斥 + 组合
比较头疼的计数题. 我们发现,放置一个棋子会使得该棋子所在的1个行和1个列都只能放同种棋子. 定义状态 $f_{i,j,k}$ 表示目前已使用了 $i$ 个行,$j$ 个列,并放置了前 $k$ 种棋子 ...
随机推荐
- 从Nest到Nesk -- 模块化Node框架的实践
文: 达孚(沪江Web前端架构师) 本文原创,转至沪江技术 首先上一下项目地址(:>): Nest:https://github.com/nestjs/nest Nesk:https://git ...
- 不允许用(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 ...
- 帧动画的创建方式 - xml方式
废话不多说,先看东西 创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画: 本文内容主要关注 xml文件 创建帧动画的方式 xml文件 ...
- RTSP连接中断重连的问题
最近在调查的一个问题. 起因是我司的一款数据链产品,15km数字图传,测试时发现视频画面经常会出现马赛克或卡顿. 图传设置了10Mbps速率,而视频码流是4Mbps,按道理不应该出现这种问题. 经过几 ...
- isinstance(obj1,class) 可以判断前者是否是后者的实例
isinstance(obj1,class) 可以判断前者是否是后者的实例
- jacascript DOM节点——节点获取与选择器API
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! DOM 操作必须等待 HTML 加载完毕之后,才可以获取节点:有两种方法: 把 script 标签放到代码 ...
- EF5中 执行 sql语句使用Database.ExecuteSqlCommand 返回影响的行数 ; EF5执行sql查询语句 Database.SqlQuery 带返回值
一: 执行sql语句,返回受影响的行数 在mysql里面,如果没有影响,那么返回行数为 -1 ,sqlserver 里面 还没有测试过 using (var ctx = new MyDbConte ...
- django 开发忘记密码通过邮箱找回功能
一.流程分析: 1.点击忘记密码====>forget.html页面,输入邮箱和验证码,发送验证链接网址的邮件====>发送成功,跳到send_success.html提示 2.到邮箱里找 ...
- 【SQL.基础构建-第一节(1/4)】
-- Tips:数据库与sql-- 一.What's 数据库-- 1.数据库(Database,DB):将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合.-- ...
- .NET Core Community 首个千星项目诞生:CAP
项目简介 在我们构建 SOA 或者 微服务系统的过程中,我们通常需要使用事件来对各个服务进行集成,在这过程中简单的使用消息队列并不能保证数据的最终一致性, CAP 采用的是和当前数据库集成的本地消息表 ...