BZOJ4767 两双手
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
题目链接:BZOJ4767
正解:组合数学+$DP$
解题报告:
推广赛终于AK辣
考虑从原点出发走到某个点的所需的两种走法的次数,是唯一确定的,那么我把从原点到每个点的所需次数算出来之后,就变成了一个只能往右或者往上的常规路径计数问题了。
这是一类有障碍的网格图计数,如果没有障碍的话,从$(0,0)$到$(n,m)$的路径条数就是$C_{n+m}^{n}$,如果有障碍的话就必须要容斥,指数级容斥显然不行,我们考虑另辟蹊径。
先把所有关键点(障碍或者目标)排序,设$f[i]$为从原点出发到达第i个关键点且不经过其他任何一个关键点的路径条数,$g[i][j]$表示从$i$到$j$的所有路径条数,那么$f[i]=g[0][i]-\sum_{j=1}^{i-1}g[j][i]*f[j]$,含义就很明显了。
这道题启发了我,容斥并非都是指数级的,对于这种有障碍的网格图计数显然可以通过排序和$DP$来做到$O(n^2)$。
//It is made by ljh2000
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
#include <bitset>
using namespace std;
typedef long long LL;
typedef long double LB;
const int MAXN = 1011;
const int mod = 1000000007;
const int MAXM = 1000011;
int n;
int Ex,Ey,Ax,Ay,Bx,By;
LL f[MAXN],jie[MAXM],nj[MAXM]; //有障碍点的网格图路径计数 struct node{ int x,y; }a[MAXN];
inline bool cmp(node q,node qq){ if(q.x==qq.x) return q.y<qq.y; return q.x<qq.x; }
inline LL fast_pow(LL x,LL y){ LL r=1; while(y>0) { if(y&1) r*=x,r%=mod; x*=x; x%=mod; y>>=1; } return r; }
inline LL C(LL x,LL y){ if(x<y) return 0; return jie[x]*nj[y]%mod*nj[x-y]%mod; }
inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void calc(int &x,int &y){
LL a1,a2,b1,b2;
a1=x*By-y*Bx; a2=Ax*By-Ay*Bx;
b1=x*Ay-Ax*y; b2=Bx*Ay-Ax*By;
if(a2==0 || b2==0) { x=-1; y=-1; return ; }
if((a1/a2)*a2!=a1 || (b1/b2)*b2!=b1) { x=-1; y=-1; return ; }
LL A=a1/a2,B=b1/b2;
x=A; y=B;
} inline void work(){
Ex=getint(); Ey=getint(); n=getint();
Ax=getint(); Ay=getint(); Bx=getint(); By=getint();
calc(Ex,Ey);
for(int i=1;i<=n;i++) {
a[i].x=getint(),a[i].y=getint();
calc(a[i].x,a[i].y);
if(a[i].x<0 || a[i].y<0 || a[i].x>Ex || a[i].y>Ey)
n--,i--;
}
a[0].x=a[0].y=0;
a[++n].x=Ex; a[n].y=Ey;
sort(a+1,a+n+1,cmp); int M=1000000;
jie[0]=1;
for(int i=1;i<=M;i++) jie[i]=jie[i-1]*i%mod;
nj[0]=1; nj[M]=fast_pow(jie[M],mod-2);
for(int i=M-1;i>=1;i--) nj[i]=nj[i+1]*(i+1)%mod; for(int i=1;i<=n;i++) {
f[i]=C(a[i].x+a[i].y,a[i].x);
if(f[i]==0) continue;
for(int j=1;j<i;j++) {
f[i]-=(f[j]*C(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x))%mod;
f[i]%=mod;
f[i]+=mod; f[i]%=mod;
}
}
printf("%lld",f[n]);
} int main()
{
work();
return 0;
}
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
BZOJ4767 两双手的更多相关文章
- bzoj4767两双手 容斥+组合
4767: 两双手 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 684 Solved: 208[Submit][Status][Discuss] ...
- BZOJ4767: 两双手【组合数学+容斥原理】
Description 老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式.老W下棋时觉得无聊,便决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v) ...
- 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 ...
- bzoj 4767: 两双手 组合 容斥
题目链接 bzoj4767: 两双手 题解 不共线向量构成一组基底 对于每个点\((X,Y)\)构成的向量拆分 也就是对于方程组 $Ax * x + Bx * y = X $ \(Ay * x + B ...
- 【BZOJ4767】两双手(动态规划,容斥)
[BZOJ4767]两双手(动态规划,容斥) 题面 BZOJ 题解 发现走法只有两种,并且两维坐标都要走到对应的位置去. 显然对于每个确定的点,最多只有一种固定的跳跃次数能够到达这个点. 首先对于每个 ...
- 【BZOJ】4767: 两双手【组合数学】【容斥】【DP】
4767: 两双手 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1057 Solved: 318[Submit][Status][Discuss] ...
- 【ZJOI2017 Round1练习&BZOJ4767】D1T3 两双手(排列组合,DP)
题意: 100%的数据:|Ax|,|Ay|,|Bx|,|By| <= 500, 0 <= n,Ex,Ey <= 500 思路:听说这是一道原题 只能往右或者下走一步且有禁止点的简化版 ...
- BZOJ 4767: 两双手 [DP 组合数]
传送门 题意: 给你平面上两个向量,走到指定点,一些点不能经过,求方案数 煞笔提一开始被题面带偏了一直郁闷为什么方案不是无限 现在精简的题意.....不就是$bzoj3782$原题嘛,还不需要$Luc ...
随机推荐
- Oulipo----poj3461(kmp模板)
题目链接:http://poj.org/problem?id=3461 和 减花布条 的题对比一下: 求s2中s1的个数kmp模板: #include<stdio.h> #include& ...
- 雨痕 的《Python学习笔记》--附脑图(转)
原文:http://www.pythoner.com/148.html 近日,在某微博上看到有人推荐了 雨痕 的<Python学习笔记>,从github上下载下来看了下,确实很不错. 注意 ...
- Html5实现iPhone开机界面
今天我突发其想,想到可以用HTML5来仿照苹果操作系统做一个能在Web平台运行的iOS. 当然,要开发出一个操作系统,等我再归山修练一百年再说吧.今天就先娱乐一下,先搞一个开机界面. 完工后的图片: ...
- 【zabbix】自定义监控项key值
说明: zabbix自带的默认模版里包括了很多监控项,有时候为了满足业务需求,需要根据自己的监控项目自定义监控项,这里介绍一种自定义监控项的方式. 1,首先编写自定义监控脚本,本文以监控httpd进程 ...
- MFC中存在的不属于任何类的全局函数,它们统统在函数名称开头加上Afx
MFC中存在的不属于任何类的全局函数,它们统统在函数名称开头加上Afx. 函数名称 说明 AfxWinInit 被WinMain(MFC提供)调用的一个函数,用做MFC GUI程序初始化的一部分,如果 ...
- PKU 2531 Network Saboteur(dfs+剪枝||随机化算法)
题目大意:原题链接 给定n个节点,任意两个节点之间有权值,把这n个节点分成A,B两个集合,使得A集合中的每一节点与B集合中的每一节点两两结合(即有|A|*|B|种结合方式)权值之和最大. 标记:A集合 ...
- JQueryEasyUI easyui-combobox 单击文本区域显示下拉菜单
//单击内容框弹出下拉菜单 $(".combo").click(function (e) { if (e.target.className == 'combo-text valid ...
- netty8---自定义编码解码器
package com.cn.codc; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Cha ...
- Android事件处理下(按键、触摸屏和滚动球的一些实现细节)
http://www.cnblogs.com/andtt/articles/2145563.html 对于按键事件,调用mDevices[i]->layoutMap->map进行映射.映射 ...
- Django学习笔记之Queryset的高效使用
对象关系映射 (ORM) 使得与SQL数据库交互更为简单,不过也被认为效率不高,比原始的SQL要慢. 要有效的使用ORM,意味着需要多少要明白它是如何查询数据库的.本文我将重点介绍如何有效使用 Dja ...