Description

n<=1e9,M,K<=100

Solution

显然任选m个港口的答案是一样的,乘个组合数即可。

考虑枚举m个港口的度数之和D

可以DP计算

记\(F_{m,D}\)为将D的度数分给m个港口的方案数

枚举新的一个度数分配给谁,然后此时可能某一个超出了限制,减掉这一个的贡献。

接下来我们可以用一个超级根把D个点连起来

prufer序简单计数即可

\(n-m+1\)个点,其中超级根出现了\(D-1\)次

就是\({n-m-1\choose D-1}(n-m)^{n-m-D}\)

总的答案为$${n\choose m}\sum\limits_{i=0}^{mK}F_{m,i}{n-m-1\choose D-1}(n-m)^{n-m-D}$$

组合数取模的时候,我们先对模数分解质因子,每次组合数相当于乘一个数除一个数

暴力枚举质因子,剩下的部分就有逆元了

注意n=m的时候会有问题需要特判。

Code

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
const int N=105;
typedef long long LL;
using namespace std;
int t,n,m,num,l,mo,f[N][N*N],cs[N*N][N],pr[N][2];
LL ksm(LL k,LL n)
{
LL s=1;
for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;
return s;
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
if(b==0) {x=1,y=0;return;}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
LL ny(int k)
{
LL x,y;
exgcd(k,mo,x,y);
return (x%mo+mo)%mo;
}
void make(int n)
{
num=0;
int n1=sqrt(n);
fo(i,2,n1)
{
if(n%i==0)
{
pr[++num][0]=i;
while(n%i==0) pr[num][1]++,n/=i;
}
}
if(n>1) pr[++num][0]=n,pr[num][1]=1;
}
int pv[N];
void mul(LL &s,LL v)
{
if(v!=0) fo(i,1,num) while(v%pr[i][0]==0) v/=pr[i][0],pv[i]++;
s=s*v%mo;
}
void dvi(LL &s,LL v)
{
fo(i,1,num) while(v%pr[i][0]==0) v/=pr[i][0],pv[i]--;
s=s*ny(v)%mo;
}
LL get(LL s)
{
fo(i,1,num) s=s*ksm(pr[i][0],pv[i])%mo;
return s;
}
int main()
{
cin>>t;
while(t--)
{
scanf("%d%d%d%d",&n,&m,&l,&mo);
if(n==m) {printf("%d\n",1%mo);continue;}
cs[0][0]=1%mo;
make(mo);
fo(i,1,m*l)
{
cs[i][0]=1%mo;
int r=min(i,l);
fo(j,1,r) cs[i][j]=((LL)cs[i-1][j]+cs[i-1][j-1])%mo;
}
f[0][0]=1;
fo(i,1,m)
{
int r=min(i*l,n-m);
f[i][0]=1;
fo(j,1,r)
{
f[i][j]=(LL)f[i][j-1]*i%mo;
if(j>l) f[i][j]=(f[i][j]-(LL)cs[j-1][l]*f[i-1][j-1-l]%mo*i%mo+mo)%mo;
}
}
memset(pv,0,sizeof(pv));
LL v=1,ans=0;int r=min(n-m,l*m);
fo(i,1,r)
{
ans=(ans+ksm(n-m,n-i-m)*f[m][i]%mo*get(v)%mo)%mo;
mul(v,n-m-i),dvi(v,i);
}
v=1;memset(pv,0,sizeof(pv));
fo(j,0,m-1) mul(v,n-j),dvi(v,j+1);
ans=ans*get(v)%mo;
printf("%lld\n",ans);
}
}

[JZOJ6244]【NOI2019模拟2019.7.1】islands【计数】【图论】的更多相关文章

  1. [JZOJ6244]【NOI2019模拟2019.7.1】Trominoes 【计数】

    Description n,m<=10000 Solution 考虑暴力轮廓线DP,按顺序放骨牌 显然轮廓线长度为N+M 轮廓线也是单调的 1表示向上,0表示向右 N个1,M个0 只能放四种骨牌 ...

  2. 【NOI2019模拟2019.7.1】为了部落 (生成森林计数,动态规划)

    Description: \(1<=n<=1e9,1<=m,k<=100\) 模数不是质数. 题解: 先选m个点,最后答案乘上\(C_{n}^m\). 不妨枚举m个点的度数和D ...

  3. [JZOJ6247]【NOI2019模拟2019.6.27】C【计数】

    Description n<=200000 Solution 比赛时没做出这道题真的太弟弟了 首先我们从小到大插入数i,考虑B中有多少个区间的最大值为i 恰好出现的次数不太好计算,我们考虑计算最 ...

  4. [JZOJ6241]【NOI2019模拟2019.6.29】字符串【数据结构】【字符串】

    Description 给出一个长为n的字符串\(S\)和一个长为n的序列\(a\) 定义一个函数\(f(l,r)\)表示子串\(S[l..r]\)的任意两个后缀的最长公共前缀的最大值. 现在有q组询 ...

  5. 【NOI2019模拟2019.6.29】字符串(SA|SAM+主席树)

    Description: 1<=n<=5e4 题解: 考虑\(f\)这个东西应该是怎样算的? 不妨建出SA,然后按height从大到小启发式合并,显然只有相邻的才可能成为最优答案.这样的只 ...

  6. 【NOI2019模拟2019.6.29】组合数(Lucas定理、数位dp)

    Description: p<=10且p是质数,n<=7,l,r<=1e18 题解: Lucas定理: \(C_{n}^m=C_{n~mod~p}^{m~mod~p}*C_{n/p} ...

  7. 【NOI2019模拟2019.7.4】朝夕相处 (动态规划+BM)

    Description: 题解: 这种东西肯定是burnside引理: \(\sum置换后不动点数 \over |置换数|\) 一般来说,是枚举置换\(i\),则\(对所有x,满足a[x+i]=a[i ...

  8. 【NOI2019模拟2019.6.27】B (生成函数+整数划分dp|多项式exp)

    Description: \(1<=n,k<=1e5,mod~1e9+7\) 题解: 考虑最经典的排列dp,每次插入第\(i\)大的数,那么可以增加的逆序对个数是\(0-i-1\). 不难 ...

  9. 【NOI2019模拟2019.7.1】三格骨牌(轮廓线dp转杨图上钩子定理)

    Description \(n,m<=1e4,mod ~1e9+7\) 题解: 显然右边那个图形只有旋转90°和270°后才能放置. 先考虑一个暴力的轮廓线dp: 假设已经放了编号前i的骨牌,那 ...

随机推荐

  1. Maven添加镜像仓库、更改本地仓库位置

    添加镜像仓库 在conf目录下的settings.xml文件的145行左右 id表示该镜像的id mirrorOf表示为哪个仓库配置镜像,central为默认的中央仓库的id,也可以使用通配符*,来匹 ...

  2. C++练习 | 最长公共字符串(DP)

    HDU 1159.Common Subsequence #include<iostream> #include<stdio.h> #include<string> ...

  3. leetcode 1282. Group the People Given the Group Size They Belong To

    There are n people whose IDs go from 0 to n - 1 and each person belongs exactly to one group. Given ...

  4. pc和手机适应js代码

    如果是手机的话跳转到新的地址 <script type="text/javascript"> function IsPC() { var userAgentInfo = ...

  5. 第十三篇 JS 操作table表格

    JS 操作table表格 这节课难度可能高一点,因为没有提前解释if判断.for循环.这节课是直接把这两样用上了,老师先简单介绍一下: if,判断语句,判断就很简单了嘛,假如说1=1(1等于1),当然 ...

  6. Nginx安装目录详解

    Nginx安装目录详解 1. 查看有关nginx的所有目录列表,输入命令  rpm -ql nginx 可以查看有关nginx目录信息,但是注意 这种命令只能是在基于yum安装的方式才可以. 2. 下 ...

  7. iOS H5页面打开APP技术总结

    iOS端H5页面打开APP的方式目前主要有两种:URL Scheme和Universal Links.其中Universal Links是iOS9.0以后推出的一种新的方案,由于它需要在iOS9.0以 ...

  8. js中 base64 转二进制

    function base64toBlob(base64,type) { // 将base64转为Unicode规则编码 let bstr = atob(base64, type), n = bstr ...

  9. redis性能指标

    1.当内存使用达到设置的最大阀值时,需要选择一种key的回收策略,可在Redis.conf配置文件中修改“maxmemory-policy”属性值. 若是Redis数据集中的key都设置了过期时间,那 ...

  10. vi编辑器中删除文件中所有字符

    在命令模式下,将光标移动到文档最上方(使用gg命令),然后输入dG,删除工作区内所有缓存数据. 如果想要删除某行文档以下的内容,将光标移动到文档相应行,然后输入dG即可.