题目:https://www.cnblogs.com/Juve/articles/11226266.html

solution:

30%:dp

设dp[k][i][j]表示经过k时间,在(i,j)的方案数

 #include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define MAXN 105
using namespace std;
ll dp[MAXN][MAXN<<][MAXN<<],t,n,m,mod;
int main(){
scanf("%lld%lld%lld%lld",&t,&mod,&n,&m);
if(n<) n=-n;
if(m<) m=-m;
if((t-n-m)&){
cout<<<<endl;
return ;
}
int xkl=;
dp[][xkl][xkl]=;
for(ll i=;i<=t;i++){
for(ll j=-t;j<=t;j++){
for(ll k=-t;k<=t;k++){
dp[i][j+xkl][k+xkl]=(dp[i][j+xkl][k+xkl]+dp[i-][j+xkl][k++xkl]+dp[i-][j+xkl][k-+xkl]+dp[i-][j-+xkl][k+xkl]+dp[i-][j++xkl][k+xkl])%mod;
}
}
}
cout<<dp[t][n+xkl][m+xkl]%mod<<endl;
return ;
}

它可以走到-t,所以要防爆

正解:(转载Barca)

我们设ri,le,up,down分别为向右左上下走的步数,且总步数为T,

然后我们只要知道,向一个方向走的步数就能得到其他的,但是我们发现光凭一个是求不出的,

我们再转化一下思路,我们设在上下方向走的步数为k,则up+down=k,

然后又因为他最后必须走到(n,m),所以向上走的步数减去向下走的步数为m,即up-down=m,

同理我们可以求出ri与le的关系,同样是两个方程,

这样我们就可以通过枚举k,来得到向各个方向走的步数,这样就能列出组合数的式子了,即:

ans=(不知为何我数学公式挂了)

$\sum \limits_{k=m}^{t-n}C_t^k*C_k^{\frac{k-m}{2}}*C_{n-k}^{\frac{t-k-n}{2}}$

-------->这有什么错吗?

但你这样也只有60分,因为mod不一定是质数

那我们可以CRT合并

先对mod分解因数,再用lucas求出mod每个因数下的ans,然后发现一个方程组

$\begin{cases} x & \equiv & ans_1 (mod\ p_1) \\ x & \equiv & ans_2 (mod\ p_2) \\ & \vdots & \\ x & \equiv & ans_n (mod\ p_n) \end{cases}$

from Rorschach_XR 为什么今天我Latex挂掉了,rp++14:38它终于好了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
#define MAXN 100005
using namespace std;
ll t,n,m,mod,ans[MAXN];
ll q_pow(ll a,ll b,ll p){
ll res=1;
while(b){
if(b&1) res=(res*a)%p;
a=(a*a)%p;
b>>=1;
}
return res%p;
}
ll tot=0,prime[MAXN];
void divide(ll p){//分解质因数
ll t=(ll)sqrt(p);
for(ll i=2;i<=t;i++){
if(p%i==0){
prime[++tot]=i;
p/=i;
}
}
if(p>1) prime[++tot]=p;
}
ll fac[MAXN];
void get_fac(ll p){
fac[0]=fac[1]=1;
for(ll i=2;i<=t;i++)
fac[i]=fac[i-1]*i%p;
}
ll C(ll n,ll m,ll p){
if(m>n) return 0;
return fac[n]*q_pow(fac[m]*fac[n-m]%p,p-2,p)%p;
}
ll lucas(ll n,ll m,ll p){
if(m==0) return 1;
return C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
ll CRT(ll ans[]){
ll res=0;
for(ll i=1;i<=tot;i++)
res=(res+mod/prime[i]*ans[i]%mod*q_pow(mod/prime[i],prime[i]-2,prime[i])%mod)%mod;
return res;
}
int main(){
scanf("%lld%lld%lld%lld",&t,&mod,&n,&m);
if(n<0) n=-n;
if(m<0) m=-m;
divide(mod);//分解质因数
for(ll i=1;i<=tot;i++){
get_fac(prime[i]);//mod(prime[i])意义下的fac
for(ll k=n;k<=t-m;k+=2)//步数不能为1
ans[i]=(ans[i]+lucas(t,k,prime[i])*lucas(k,(k-n)/2,prime[i])%mod*lucas(t-k,(t-m-k)/2,prime[i])%mod)%mod;
}
printf("%lld\n",CRT(ans)%mod);
return 0;
}

HZOI20190722 B visit 组合数+CRT合并的更多相关文章

  1. 【BZOJ2142】礼物 组合数+CRT

    [BZOJ2142]礼物 Description 小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi.请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在 ...

  2. P2480 [SDOI2010]古代猪文 Lucas+CRT合并

    \(\color{#0066ff}{ 题目描述 }\) 猪王国的文明源远流长,博大精深. iPig在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为N.当然,一种语言如果字数很多,字典也相应会 ...

  3. 华农oj 2192: hzk又在打人【CRT合并/待补】

    2192: hzk又在打人 Time Limit: 12 Sec Memory Limit: 512 MB Submit: 52 Solved: 1 [Submit][Status][Web Boar ...

  4. 组合数取模(lucas定理+CRT合并)(AC)

    #include<bits/stdc++.h> #define re register #define int long long using namespace std; ; inlin ...

  5. 【CF896D】Nephren Runs a Cinema 卡特兰数+组合数+CRT

    [CF896D]Nephren Runs a Cinema 题意:一个序列中有n格数,每个数可能是0,1,-1,如果一个序列的所有前缀和都>=0且总和$\in [L,R]$,那么我们称这个序列是 ...

  6. bzoj3782上学路线(Lucas+CRT+容斥DP+组合计数)

    传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3782 有部分分的传送门:https://www.luogu.org/problemnew/ ...

  7. BZOJ_2142_礼物_扩展lucas+组合数取模+CRT

    BZOJ_2142_礼物_扩展lucas+组合数取模 Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同 ...

  8. OI中组合数的若干求法与CRT

    OI中组合数的若干求法与CRT 只是下决心整理一下子呢~ 说明:本篇文章采用\(\binom{a}{b}\)而不是\(C_{a}^b\),以\(p\)指代模数,\(fac_i\)指代\(i!\),\( ...

  9. 5.20 省选模拟赛 求和 组合数的性质 EGF CRT

    LINK:求和 绝妙的一道题目.没做绝对亏了. 对于第一个subtask 考虑直接递推出组合数. 对于第二个subtask 考虑EGF 设两个EGF 都只含偶数项指标且系数为1的那种 一个到n一个到m ...

随机推荐

  1. 廖雪峰Java16函数式编程-2Stream-6reduce

    1. 聚合方法 Stream.reduce()是一个Stream的聚合方法:把一个Stream的所有元素聚合成一个结果 例如: Stream.of(1, 2, 3, 4, 5).count(); // ...

  2. Java导出pdf文件数据

    提示:导出pdf文件,需要3个jar包iText-2.1.5.jar,iTextAsian.jar,iText-rtf-2.1.4.jar. public boolean outputPdfJhsy( ...

  3. 软件设计师_朴素模式匹配算法和KMP算法

    1.从主字符串中匹配模式字符串(暴力匹配) 2. KMP算法

  4. for循环总结

    1.冒泡排序的总结:其实这个很简单的理解,就是用数组里面的第0个元素(也就是[]里面的第一个数,按照数组的话是第一个,让他们进行挨个比较),示例: 排序前: 14 62 38 41 53 62 71 ...

  5. POJ-2253-Frogger-/Floyd-Warshall/

    Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sit ...

  6. low版九九乘法表

    # while循环实现九九乘法表num_one = 1while num_one <= 9: num_two = 1 while num_two <= num_one: print(&qu ...

  7. 关于ueditor 文本框

    遇到一个问题,需要将从ueditor中的获得的带格式的文本,从数据库中取出,在放回到 ueditor中去,但是 文本中\n总是截断字符串,出现 这种情况,后面的字符就不能算到里面去了,程序就报错了. ...

  8. <jquery>基本的模态框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. selenium基础(多表单切换、多窗口切换)

    一.多表单的切换 frame:HTML页面中的一中框架,主要作用是在当前页面中指定区域显示另一页面元素:              (HTML语言中,frame/iframe标签为表单框架) 在web ...

  10. Python对象和类

    Python 里的所有数据都是以对象形式存在的,对象是类的实例. 定义类(class) 使用class来定义一个类. 比如,定义一个cat类,如下: class Cat(): def __init__ ...