P4478 [BJWC2018]上学路线

Description

小B 所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M)。

小B 家住在西南角,学校在东北角。现在有T 个路口进行施工,小B 不能通过这些路口。小B 喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走;而小B又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条。由于答案可能很大,所以小B 只需要让你求出路径数mod P 的值。



\((0,0)\to (N,M)\)的路径数是\(C_{n+m}^n\)

\(f[i]\)表示第一个到达的障碍是\(i\)时\((0,0)\to (x_i,y_i)\)的路径数

\[()f[i]=C_{x_i+y_i}^{x_i}-\sum C_{x_i+y+_i-x_j-y_j}^{x_i-x_j}\times f[j](x_j\leq x_i\wedge y_j\leq y_i) \]

\(1019663265\)一看就不是质数啊$=3\times 5\times 6793\times 10007 $

用中国剩余定理合并


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define M 1000010
using namespace std;

LL n,m,t,p,A[M],B[M],inv[M],f[201],ans1,ans2,ans3,ans4;

struct vv { LL x,y;} a[201];
bool cmp(vv a,vv b){return (a.x!=b.x? a.x<b.x : a.y<b.y);}

LL C(LL x,LL y,LL p)
{
    if(y>x) return 0;
    if(x<p && y<p) return A[x]*B[y]%p*B[x-y]%p;
    return C(x/p,y/p,p)*C(x%p,y%p,p)%p;
}

LL solve(LL p)
{
    LL ans=0;
    A[0]=B[0]=inv[1]=1;
    for(int i=2;i<p;i++) inv[i]=(p-p/i)*inv[p%i]%p;
    for(int i=1;i<p;i++) A[i]=A[i-1]*i%p;
    for(int i=1;i<p;i++) B[i]=B[i-1]*inv[i]%p;
    for(int i=1;i<=t;i++)
    {
        f[i]=C(a[i].x+a[i].y,a[i].x,p);
        for(int j=1;j<i;j++) if(a[j].x<=a[i].x && a[j].y<=a[i].y)
            f[i]=(f[i]-f[j]*C(a[i].x+a[i].y-a[j].x-a[j].y,a[i].y-a[j].y,p)%p+p)%p;
    }
    ans=C(n+m,m,p);
    for(int i=1;i<=t;i++) ans=(ans-f[i]*C(n+m-a[i].x-a[i].y,n-a[i].x,p)%p+p)%p;
    return ans;
}

LL ksm(LL x,LL y,LL p)
{
    LL z=1;
    for(;y>1;y>>=1, x=x*x%p) if(y&1) z=z*x%p;
    return x*z%p;
}

int main()
{
    scanf("%lld%lld%lld%lld",&n,&m,&t,&p);
    for(int i=1;i<=t;i++) scanf("%lld%lld",&a[i].x,&a[i].y);
    sort(a+1,a+1+t,cmp);
    if(p==1000003){ printf("%lld",solve(p)); return 0;}
    ans1=solve(3)*(p/3)%p*((p/3)%3)%p;  ans4=solve(10007)*(p/10007)%p*ksm(p/10007,10005,10007)%p;
    ans2=solve(5)*(p/5)%p*ksm(p/5,3,5)%p; ans3=solve(6793)*(p/6793)%p*ksm(p/6793,6791,6793)%p;
    printf("%lld",((ans1+ans2)%p+(ans3+ans4)%p)%p);
}

原文地址:https://www.cnblogs.com/ZUTTER/p/10371492.html

时间: 2024-10-10 20:23:50

P4478 [BJWC2018]上学路线的相关文章

BZOJ 1266 上学路线route(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1266 题意:给出一个无向图,每条边有长度和代价.求出1到n的最短路.之后删掉一些边使得1到n的最短路变大?在此情况下使得删掉边的代价之和最小. 思路:首先求出每个点到1和n的最短路.之后可以确定每条边是否为关键边(就是最短路上的边).将关键边建立网络流图,求最小割即可. struct node { int v,cap,next; }; node edges[N]; int head[N

Tyvj P2207 上学路线route

P2207 上学路线route 正反两遍spfa,判断某条边是否是在最短路上,如果是的话就建边,跑最大流 1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define maxn 250000 7 #define inf 0x3f3f3f3f 8 int n,m,src,dec,ans,cur[max

【bzoj3782】上学路线 dp+容斥原理+Lucas定理+中国剩余定理

题目描述 小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M).小C家住在西南角,学校在东北角.现在有T个路口进行施工,小C不能通过这些路口.小C喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走:而小C又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条.由于答案可能很大,所以小C只需要让你求出路径数mod P的值. 输入 第一行,四个整数N.M.T.P. 接下来的T行,每行两个整数,表示施工的路口的坐标. 输出 一

2505 上学路线

2505 上学路线 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 因为是学生,所以显然小A每天都要上学.小A所在的城市的道路构成了一个n*m的网格,每条道路都是可以单向通行的.小A家在点(1,1),学校在点(n,m).在不移出边界的情况下,小A可以从点(x,y)移动到点(x+1,y)或(x,y+1).为了追求新鲜感,小A经常走不同的道路去上学.有一天,小A突发奇想:到底他可以有多少种不同的上学路线呢?

BZOJ1266: [AHOI2006]上学路线route

1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 1273  Solved: 435[Submit][Status] Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上学需要的最少时间吧

【BZOJ3782】上学路线 组合数+容斥+CRT

[BZOJ3782]上学路线 Description 小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M).小C家住在西南角,学校在东北角.现在有T个路口进行施工,小C不能通过这些路口.小C喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走:而小C又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条.由于答案可能很大,所以小C只需要让你求出路径数mod P的值. Input 第一行,四个整数N.M.T.P. 接下来的T

codevs——2693 上学路线(施工)

2693 上学路线(施工) 时间限制: 2 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 问题描述 你所在的城市街道好像一个棋盘,有a条南北方向的街道和b条东西方向的街道. 南北方向a条街道从西到东依次编号为1到a,而东西方向的b条街道从南到北依次编号为1到b,南北方向的街道i和东西方向的街道j的交点记为(i,j). 假定你住在(1,1)处,而学校在(a,b)处,你骑自行车去上学,自行车只能沿着街道走,而且为了缩短时间只允许沿着东.北方向

BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)

第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的最短路),然后跑一遍最大流就OK了. --------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #

bzoj 1266 1266: [AHOI2006]上学路线route

1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2356  Solved: 841[Submit][Status][Discuss] Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上