【NOI2015模拟8.17】最短路(shortest)//2018.2.5
2018-02-06 20:51
197 查看
题目
Description小Y最近学得了最短路算法,一直想找个机会好好练习一下。话虽这么说,OJ上最短路的题目都被他刷光了。正巧他的好朋友小A正在研究一类奇怪的图,他也想凑上去求下它的最短路。
小A研究的图可以这么看:在一个二维平面上有任意点(x,y)(0<=x<=N,0<=y<=M,且x,y均为整数),且(x,y)向(x-1,y)(必须满足1<=x)和(x,y-1)(必须满足1<=y)连一条边权为0的双向边。
每个点都有一个非负点权,不妨设(x,y)的权值为F[x][y],则有:
1.x=0或y=0:F[x][y]=1;2.其他情况:F[x][y]=F[x-1][y]+F[x][y-1]。
现在,小Y想知道(0,0)到(N,M)的最短路,即使得经过的点的权值之和最小。为了炫耀自己学过最短路算法,他决定和你进行一场比赛,看谁的程序跑得快。然则小Y没有学过高精度算法,所以他希望输出答案时只输出答案模1000000007后的值。
Input
一行两个正整数N,M,表示图的大小。
Output
一行一个整数Ans,表示答案模1000000007后的值。
Hint
10%的数据满足N,M<=20;
30%的数据满足N,M<=100;
60%的数据满足min(N,M)<=100;
100%的数据满足N*M<=10^12。
解题思路
这个图就是个划分后的矩形,也就是网格图。
20分看这里:暴力求出每个点权,然后使用DP或最短路算法。总效率O(NM)或O(NMLog(NM))。答案的范围在Int64/long long范围内。
60分看这里:暴力求出每个点权,然后使用DP或最短路算法。使用高精度储存答案。总效率O(NMA)或O(NMALog(NM))。其中A为答案长度。
观察原图,将x+y值相同的点(x,y)归为一层,将层按x+y值从小到大看,会发现其实整个图是杨辉三角的一部分。
![这里写图片描述](https://img-blog.csdn.net/20180206194840569?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzk4OTc4Njc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
容易看出,每层权值最小的点或都在最左侧或都在最右侧。由于N,M互换并不影响答案,所以假如每层权值最小的点都在最右侧,则交换N,M,保证每层权值最小的点都在最左侧。
从本质上说,就是该图的最短路是确定的,都是沿着矩形外围一圈走,且一开始先走矩形长的一边。
保证N<=M,那么答案可以直接算出,也就是M+C[M][0]+C[M+1][1]+…+C[M+N]
。
120分看这里:用一个矩阵维护C[K][0]-C[K]
的值。通过快速幂可以迅速得出C[M][0]-C[M]
的值,由于答案涉及的排列数只有N+1项,所以接着逐级递推即可。总效率O(N^3LogM)。
200分看这里:把后面的排列数分别拆解开看:
C[M][0]=1; C[M+1][1]=(M+1)/1; C[M+2][2]=(M+1)*(M+2)/(1*2)=C[M+1][1]*((M+2)/2); C[M+3][3]=C[M+2][2]*((M+3)/3); … C[M+N] =C[M+N-1][N-1]*((M+N)/N)。
由于模的数是一个素数,所以除以数a直接转化成乘数a的逆元。接着直接递推即可。总效率O(NLogN)。
【再详细一点吧】其实就是费马小定理……
假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),例如:假如a是整数,p是质数,则a,p显然互质(即两者只有一个公约数1),那么我们可以得到费马小定理的一个特例,即当p为质数时候, a^(p-1)≡1(mod p)。实际上,它是欧拉定理的一个特殊情况(即
可能会发现跟题目没有什么区别,但是题目其实就是一个杨辉三角形,让我们求1到C(n,m)的….其实也就是求C(n,n+m),所以用逆元,而逆元要用到费马小定理,而x的y次方又要用到快速幂,所以就是正解了;
代码
#include<iostream> #include<cstdio> #include<cmath> using namespace std; const int inf=1000000007; long long x=1,y=1,n,m; long long sst(long long b,long long a) { long long ans=1; while (a) { if (a&1) ans=(ans*b)%inf; a>>=1; b=(b*b)%inf; } return ans; } int main() { scanf("%lld%lld",&n,&m); long long t=0; if (n<m) { t=n;n=m;m=t;} for (long long i=n+2;i<=n+m+1;i++) x=(x*i)%inf; //x的阶乘 for (long long i=1;i<=m;i++) y=(y*i)%inf;//y的阶乘 printf("%lld",(x*sst(y,inf-2)%inf+n)%inf); //逆元 return 0; }
相关文章推荐
- 3777. 【NOI2015模拟8.17】最短路(shortest)
- JZOJ.3777【NOI2015模拟8.17】最短路(shortest)
- 【NOI2015模拟8.17】最短路(shortest)
- JZOJ3777. 【NOI2015模拟8.17】最短路(shortest)
- 最短路【NOI2015模拟8.17】
- jzoj3819 [NOI2015模拟9.9]取石子
- JZOJ 3789. 【NOI2015模拟8.20】编辑器
- NOI2015模拟SXK 字符串游戏 后缀数组预处理+主席树查询
- 【NOIP2014模拟8.17】Magical GCD//2018.2.5
- 【JZOJ3773】【NOI2015模拟8.15】小 P 的烦恼
- 【jzoj3771】【NOI2015模拟8.15】【小 Z 的烦恼】
- 【NOI2015模拟1.10】B组黑白树
- JZOJ3975. 【NOI2015模拟1.17】串
- JZOJ3789. 【NOI2015模拟8.20】编辑器
- hdu 5373 The shortest problem 2015多校联合训练赛#7 模拟
- 【NOI2015模拟1.17】⑨
- JZOJ.3769【NOI2015模拟8.14】A+B
- A+B【NOI2015模拟8.14】
- 【JZOJ 3769】【NOI2015模拟8.14】A+B
- 【jzoj3773】【NOI2015模拟8.15】【小 P 的烦恼】【动态规划】