BZOJ 3782: 上学路线 [Lucas定理 DP]
3782: 上学路线
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 192 Solved: 75
[Submit][Status][Discuss]
Description
Input
Output
HINT
终于A掉了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e6+;
inline ll read(){
char c=getchar();ll x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
ll n,m,P;
int t;
struct Point{
ll x,y;
bool operator <(const Point &a)const{
return x<a.x||(x==a.x&&y<a.y);
}
}a[];
namespace A{
ll P=;
ll inv[N],fac[N],facInv[N];
void ini(){
inv[]=fac[]=facInv[]=;
for(int i=;i<=P;i++){
if(i!=) inv[i]=-P/i*inv[P%i]%P;
inv[i]+=inv[i]<?P:;
fac[i]=fac[i-]*i%P;
facInv[i]=facInv[i-]*inv[i]%P;
}
}
ll C(int n,int m){
if(n<m) return ;
return fac[n]*facInv[m]%P*facInv[n-m];
}
ll Lucas(ll n,ll m){
if(n<m) return ;
ll re=;
for(;m;n/=P,m/=P) re=re*C(n%P,m%P)%P;
return re;
}
ll f[];
void dp(){
for(int i=;i<=t;i++){
f[i]=Lucas(a[i].x+a[i].y,a[i].x);//printf("fo %d %lld\n",i,f[i]);
for(int j=;j<i;j++)
if(a[j].x<=a[i].x&&a[j].y<=a[i].y)
f[i]=(f[i]- Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%P +P)%P;
//printf("oh %d %lld %lld \n",j ,Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%P ,f[i]);
//printf("f %d %lld\n",i,f[i]);
}
}
void solve(){
ini();
dp();
printf("%lld",f[t]);
}
}
namespace B{
ll P[]={,,,,};
const int N=1e5+;
ll Pow(ll a,ll b,ll P){
if(a==) return ;
ll re=;
for(;b;b>>=,a=a*a%P)
if(b&) re=re*a%P;
return re;
}
ll Inv(ll a,ll P){return Pow(a,P-,P);}
ll inv[N][],fac[N][],facInv[N][];
void ini(){
for(int j=;j<=;j++){
int MOD=P[j];
inv[][j]=fac[][j]=facInv[][j]=;
for(int i=;i<=MOD;i++){
if(i!=) inv[i][j]=-MOD/i*inv[MOD%i][j]%MOD;
if(inv[i][j]<) inv[i][j]+=MOD;
fac[i][j]=fac[i-][j]*i%MOD;
facInv[i][j]=facInv[i-][j]*inv[i][j]%MOD;
}
}
}
ll C(int n,int m,int j){//printf("C %d %d %d %lld %lld\n",n,m,j,fac[n][j],facInv[m][j]);
if(n<m) return ;
ll p=P[j];
return fac[n][j]*facInv[m][j]%p*facInv[n-m][j]%p;
}
ll lucas(ll n,ll m,int j){
if(n<m) return ;
ll MOD=P[],a=,p=P[j];
for(;m;m/=p,n/=p) a=a*C(n%p,m%p,j)%p;
return a*(MOD/p)%MOD*Inv(MOD/p,p)%MOD;
}
ll Lucas(ll n,ll m){//printf("Lucas1 %lld %lld\n",n,m);
ll re=,MOD=P[];
for(int i=;i<=;i++)
re=(re+lucas(n,m,i))%MOD;
return re;
} ll f[];
void dp(){
for(int i=;i<=t;i++){
f[i]=Lucas(a[i].x+a[i].y,a[i].x);//printf("fo %d %lld\n",i,f[i]);
for(int j=;j<i;j++)
if(a[j].x<=a[i].x&&a[j].y<=a[i].y)
f[i]=(f[i]- Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%P[] +P[])%P[];
//printf("oh %d %lld %lld \n",j ,Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j] ,f[i]);
// printf("fn %d %lld\n",i,f[i]);
}
}
void solve(){
ini();
dp();
//for(int i=1;i<=t;i++)
// printf("Point %lld %lld %lld\n",a[i].x,a[i].y,f[i]);
printf("%lld",f[t]);
}
}
int main(){
freopen("in","r",stdin);
n=read();m=read();
t=read();P=read();
for(int i=;i<=t;i++) a[i].x=read(),a[i].y=read();
a[++t].x=n;a[t].y=m;
sort(a+,a++t);
if(P==) A::solve();
else B::solve();
}
BZOJ 3782: 上学路线 [Lucas定理 DP]的更多相关文章
- bzoj 3782 上学路线 卢卡斯定理 容斥 中国剩余定理 dp
LINK:上学路线 从(0,0)走到(n,m)每次只能向上或者向右走 有K个点不能走求方案数,对P取模. \(1\leq N,M\leq 10^10 0\leq T\leq 200\) p=10000 ...
- BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
我们枚举第一个经过的坏点,然后DP即可. 状态转移方程不是难点,难点在于组合数的处理. 将狼踩尽的博客中有很详细的证明过程,但是我只记住了结论 $n=a_1 * p^k+a_2*p^k-1...$ $ ...
- BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp
其实呢,扩展中国剩余定理还有一种理解方式:就是你有一坨东西,形如:$A[i]\equiv B[i](mod$ $P[i])$. 对于这个东西,你可以这么思考:如果最后能求出一个解,那么这个解的增量一定 ...
- BZOJ 3782 上学路线
首先这个题需要dp.dp[i]=C(x[i]+y[i],x[i])-Σdp[j]*C(x[i]-x[j]+y[i]-y[j],x[i]-x[j])(x[i]>=x[j],y[i]>=y[j ...
- bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP
1902: Zju2116 Christopher Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 172 Solved: 67[Submit][Stat ...
- [CTSC2017]吉夫特(Lucas定理,DP)
送70分,预处理组合数是否为偶数即可. 剩下的数据,根据Lucas定理的推论可得当且仅当n&m=n的时候,C(n,m)为奇数.这样就可以直接DP了,对于每个数,考虑它对后面的数的影响即可,直接 ...
- 洛谷P3773 [CTSC2017]吉夫特(Lucas定理,dp)
题意 满足$b_1 < b_2 < \dots < b_k$且$a_{b_1} \geqslant a_{b_2} \geqslant \dots \geqslant a_{b_k} ...
- Bzoj 4403: 序列统计 Lucas定理,组合数学,数论
4403: 序列统计 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 328 Solved: 162[Submit][Status][Discuss] ...
- BZOJ - 2142 礼物 (扩展Lucas定理)
扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...
随机推荐
- Shell菜单脚本
今天在这儿给大家分享一个我简单编写的Shell菜单脚本,傻瓜式的人机交互,人人都可以操作linux. #!/bin/sh #Shell菜单演示 function menu () { cat <& ...
- 遍历Map集合:java.util.Map.Entry、KeySet两种方式
遍历Map集合的两种方式: 1.用KeySet Map.keySet(),返回一个存放所有key的set集合,通过遍历集合,根据key值取出所有的value值. Map<String,Strin ...
- C++ 默认参数(转载)
函数的默认参数值,即在定义参数的时候同时给它一个初始值.在调用函数的时候,我们可以省略含有默认值的参数.也就是说,如果用户指定了参数值,则使用用户指定的值,否则使用默认参数的值. void Func( ...
- Micropython TPYBoard 智能温控小风扇资料分享
南方都下大雪了,苦逼的北方还没下雪,天寒地冻,不过这几天办公室空调开太大了就想到做一个温控小风扇,简单模型出来了.等夏天一定做一个美观精致的小风扇送给女朋友(如果有的话QAQ)话不多说直接上干货.(跪 ...
- 003_JS基础_面向对象基础
3.1 对象 引入:在js中表示一个人的信息(name, gender, age)通过var申明三个变量,但是这样使用基本数据类型的变量,他们是互相独立的,没有联系: 此时就需要使用对象,对象是 ...
- 【笔记】BFC 模型知识整理
网上看了很多 BFC 的概念,发现都说得不是很完整和深入,刚好最近看了一些视频教程说到了 BFC 概念所以记录一下. BFC 的概念: BFC 全称:Block format context 块级格式 ...
- 前端之CSS介绍--选择器
一.CSS简介 介绍 css我们称呼层叠样式表(英文全称:Cascading Style Sheets).它是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等 ...
- get最简单直接粗爆git与github教程
Git是分布式版本控制系统(可以理解为文件管理拓展工具) github一个在线文件托管系统(可以理解为一个在线云盘) 准备工作,在git官网下载git软件件,安装git软件,以windows.为例,下 ...
- Effective Java 第三版——28. 列表优于数组
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- mysql 列转行,合并字段
数据表: 列转行:利用max(case when then) max---聚合函数 取最大值 (case course when '语文' then score else 0 end) ---判断 ...