[多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学)

题面

青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献从小到大排成一排,以便于发放奖金。每只羊都会得到数值在 1~m 的奖金,并且第 i 只羊的奖金应为第 i+1只羊的约数(即满足 ai|ai+1)。现在包包大人想知道一共有多少种不同的发放奖金的方式(两种发放奖金的方式不同是指在两种发放奖金的方式中存在某只羊拿到的奖金不同)

分析

我们发现,序列中不同的数最多只有\(O(\log m)\)个,因为后面的数至少是前面的数*2.

那么我们可以dp求出长度为\(i\)的每个数互不相同的序列个数。设\(dp[i][j]\)表示长度为\(i\),结尾为\(j\)的本质不同序列个数 .那么可以用\(dp[i][j]\)去更新\(dp[i+1][j*k] (jk \leq n,k \in \mathbb{N},k \neq 1)\)

for(int i=1;i<log2m;i++){//a序列里本质不同的数只有O(logm)个,因此不用对n个数dp,
for(int j=1;j<=m;j++){
for(int k=2;j*k<=m;k++){
dp[i+1][j*k]+=dp[i][j];
dp[i+1][j*k]%=mod;
}
}
}

因为1~m的数的约数个数和为\(O(m \log m)\),所以dp的复杂度是\(O(m \log ^2m)\)

然后考虑把序列扩展到长度为n。对于长度为\(i\)的每个数互不相同的序列,我们记它的方案数为\(cnt[i]=\sum_{j=1}^m dp[i][j]\).我们把长度为n的序列分成\(i\)段,每段对应长度为\(i\)数列中的一个值。用插板法,从\(n-1\)个间隔中选\(i-1\)个插板,方案数是\(C_{n-1}^{i-1}\)

因此答案是\(\sum_{i=1}^{\log_2m} C_{n-1}^{i-1}cnt[i]\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxlogm 23
#define maxn 1000000
#define maxm 1000000
#define mod 1000000007
using namespace std;
typedef long long ll;
ll fact[maxn+5],invfact[maxn+5];
inline ll fast_pow(ll x,ll k){
ll ans=1;
while(k){
if(k&1) ans=ans*x%mod;
x=x*x%mod;
k>>=1;
}
return ans;
}
ll inv(ll x){
return fast_pow(x,mod-2);
}
void ini(int n){
fact[0]=1;
for(int i=1;i<=n;i++) fact[i]=fact[i-1]*i%mod;
invfact[n]=inv(fact[n]);
for(int i=n-1;i>=0;i--) invfact[i]=invfact[i+1]*(i+1)%mod;
}
inline ll C(int n,int m){
return fact[n]*invfact[n-m]%mod*invfact[m]%mod;
} int n,m;
int log2m;
ll dp[maxlogm+5][maxm+5];//长度为i,结尾为j的本质不同序列个数
ll cnt[maxlogm+5];//长度为i的序列个数, 即sum(dp[i][j]) (1<=j<=m)
int main(){
scanf("%d %d",&m,&n);
log2m=log2(m)+1;
ini(max(n,log2m));
for(int i=1;i<=m;i++) dp[1][i]=1;
for(int i=1;i<log2m;i++){//a序列里本质不同的数只有O(logm)个,因此不用对n个数dp,
for(int j=1;j<=m;j++){
for(int k=2;j*k<=m;k++){
dp[i+1][j*k]+=dp[i][j];
dp[i+1][j*k]%=mod;
}
}
}
for(int i=1;i<=log2m;i++){//a序列里本质不同的数只有O(logm)个,因此不用对n个数dp,
for(int j=1;j<=m;j++){
cnt[i]+=dp[i][j];
cnt[i]%=mod;
}
}
ll ans=0;
for(int i=1;i<=log2m&&i<=n;i++){
ans+=cnt[i]*C(n-1,i-1)%mod;//把n个数分成i段,每段对应序列中的一个数,插板法
ans%=mod;
}
printf("%lld\n",ans);
}

[多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)的更多相关文章

  1. [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)

    [多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...

  2. [多校联考2019(Round 5 T2)]蓝精灵的请求(二分图染色+背包)

    [多校联考2019(Round 5)]蓝精灵的请求(二分图染色+背包) 题面 在山的那边海的那边住着 n 个蓝精灵,这 n 个蓝精灵之间有 m 对好友关系,现在蓝精灵们想要玩一个团队竞技游戏,需要分为 ...

  3. [多校联考2019(Round 4 T1)][51nod 1295]Xor key(可持久化trie)

    [51nod 1295]Xor key(可持久化trie) 题面 给出一个长度为n的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] 至 A[R] ...

  4. [多校联考2019(Round 4 T2)][51nod 1288]汽油补给(ST表+单调栈)

    [51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的 ...

  5. 【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7

    此次比赛为厦门一中出题.都是聚劳,不敢恭维. 莫名爆了个0,究其原因,竟然是快读炸了……很狗,很难受. 话不多说,来看看题: [T1] 题意: 样例: PS:1<=h[i]<=100000 ...

  6. [2019多校联考(Round 6 T3)]脱单计划 (费用流)

    [2019多校联考(Round 6 T3)]脱单计划 (费用流) 题面 你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两 ...

  7. 【BZOJ5498】[十二省联考2019]皮配(动态规划)

    [BZOJ5498][十二省联考2019]皮配(动态规划) 题面 BZOJ 洛谷 题解 先考虑暴力\(dp\),设\(f[i][j][k]\)表示前\(i\)所学校,有\(j\)人在某个阵营,有\(k ...

  8. 三校联考 Day3

    三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...

  9. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

随机推荐

  1. vscode 代码缩进2格

    "editor.detectIndentation":false,

  2. BZOJ 4773: 负环 倍增Floyd

    现在看来这道题就非常好理解了. 可以将问题转化为求两点间经过 $k$ 个点的路径最小值,然后枚举剩余的那一个点即可. #include <cstdio> #include <cstr ...

  3. BZOJ 3545: [ONTAK2010]Peaks 启发式合并 + 离线 + Splay

    Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询 ...

  4. luogu P1352 没有上司的舞会 x

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  5. (65)CRC32校验C语言版本

    #include<iostream> # include <stdio.h> # include <string.h> typedef unsigned int u ...

  6. python-opencv中的cv2.inRange函数

    本次目标是将一副图像从rgb颜色空间转换到hsv颜色空间,颜色去除白色背景部分 具体就调用了cv2的两个函数,一个是rgb转hsv的函数 具体用法 hsv = cv2.cvtColor(rgb_ima ...

  7. 聊聊spring-boot-starter-data-redis的配置变更

    本文主要研究一下spring-boot-starter-data-redis的配置变更 配置变更 以前是spring-boot的1.4.x版本的(spring-data-redis为1.7.x版本), ...

  8. 20175308 2018-2019-2 实验四 《Android开发基础》实验报告

    20175308 2018-2019-2 实验四 <Android开发基础>实验报告 实验要求 参考 Android开发简易教程 完成云班课中的检查点,也可以先完成实验报告,直接提交.注意 ...

  9. k8s网络通信

    K8s有三种网络, 1.节点网络 2.pod网络 3.service集群网络,由kube-proxy来负责

  10. FineReport打印方式(转)

    1. 报表打印机制 各种打印的运行机制,都是选择打印时,先根据报表内容,在服务器的内存中将页面中的内容全部生成完毕,即生成对应格式的对象:然后再由serverlet直接推送给客户端,最后根据选择的打印 ...