[10.31模拟赛]T3

Description

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

Input

一行两个正整数\(n\),\(k\),满足(\(1<=n\),\(k<=1000000\))

Output

一行一个整数代表发放奖金的方案对\(1000000007\)取模的结果

Sample Input

6 4

Sample Output

3 9

Data Constraint

对于\(20\)%的数据:\(n,k<=10\)
对于\(50\)%的数据:\(n,k<=2000\)
对于\(100\)%的数据:\(n,k<=1000000\)

Limit

\(2000ms\) \(512M\)

Solution

不妨设第\(i\)只羊获得的奖金为\(ai\),那么\(a\)序列中不同的数的个数不超过\(O(logn)\),且所有数字按升序排列,因此可以枚举\(a\)序列中不同的数的个数\(d\),不妨假设这些不同的数分别为\(p1\),\(p2\),\(p3\)...\(pd\),考虑统计\(p\)序列的个数: 用\(f[i][j]\)表示长度为\(i\)且\(pi=j\)的\(p\)序列个数,用\(f[i+1][t*j]+=f[i][j]\)来更新即可。
那么\(cnt[i]=\sum f[i][j]\)即为长为\(i\)的\(p\)序列个数。
接下来考虑求出\(p1\),\(p2\),\(p3\)...\(pd\)放入\(a\)序列中的方案数,用隔板法可以求出这个方案数为\(C(k-1,d-1)\),因而总的方案数为
\(\sum^{logk}_{i=1}cnt[d]\ast C(k-1,d-1)\)

Code

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define MOD 1000000007
#define N 1000020
#define M 22
#define MAXN 10010
ll n, k, ans;
ll H[N], f[M][N], cnt[M];
inline ll read() {
    ll s = 0, w = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    return s * w;
}
inline ll Pow(ll a, ll k) {
    ll ans = 1;
    while (k) {
        if (k & 1) (ans *= a) %= MOD;
        (a *= a) %= MOD;
        k >>= 1;
    }
    return ans;
}
inline ll Inv(int a) {
    return Pow(a, MOD - 2);
}
inline void Init() {
    H[0] = 1;
    for (register int i = 1; i <= N; i++)
        H[i] = (H[i - 1] * i) % MOD;
}
inline ll C(ll x, ll y) {
    return H[x] * Inv(H[y]) % MOD * Inv(H[x - y]) % MOD;
}
int main() {
    freopen("commend.in", "r", stdin);
    freopen("commend.out", "w", stdout);
    Init();
    n = read(), k = read();
    for (register int i = 1; i <= n; i++)
        f[1][i] = 1;
    for (register int i = 1; i < M - 1; i++)
        for (register int j = 1; j <= n; j++)
            for (register int k = j + j; k <= n; k += j)
                (f[i + 1][k] += f[i][j]) %= MOD;
    for (register int i = 1; i < M; i++)
        for (register int j = 1; j <= n; j++)
            (cnt[i] += f[i][j]) %= MOD;
    for (register int i = 1; i <= k && i < M; i++)
        (ans += cnt[i] * C(k - 1, i - 1) % MOD) %= MOD;
    cout << ans;
    return 0;
}

原文地址:https://www.cnblogs.com/Agakiss/p/11779203.html

时间: 2024-07-29 12:49:31

[10.31模拟赛]T3的相关文章

10.31 模拟赛

10.31 模拟赛 A LIS 考虑每个数字前从 $ m $ 降序构造到 $ a_i $ 即可. #include <iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define MAXN 300006 int n , m , k; int A[MAXN]; vector<int&g

[10.5模拟赛]T3

T3 Description 小\(Z\)是\(ZRP(Zombies' Republic of Poetry\),僵尸诗歌共和国\()\)的一名诗歌爱好者,最近他研究起了诗词音律的问题. 在过去,诗词是需要编成曲子唱出来的,比如下面这首<菩萨蛮>,唱出来的话其对应的音符就是这样的: 南园满地堆轻絮, 愁闻一霎清明雨 1 1 5 5 6 6 5 4 4 3 3 2 2 1 因而可以发现,"1 1 5 5 6 6 5 4 4 3 3 2 2 1" 这串音符就成为了研究音律的

2019.10.18模拟赛T3

题目大意: 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)>n](n\leq 10^{10})$的值. 题解: 这题貌似有n多种做法... 为了更好统计,把原式变为$n^2-\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)\leq n]$. 然后开始毒瘤... 首先,考虑枚举$lcm(i,j)$,设为$d$,计算有多少对$i.j$的最小公倍数为$d$. 设$i=p_1^{a_1}p_2^{a_2}\

2019.10.31模拟赛

说在前面 考场遇见原题??? 上午刚做的 下午就\(T3\)考到了\(2333\) 然而还是因为忘了取模挂了28分 T1 Dove下跳棋 数据太水输出n-1可得90 Dove 喜爱下跳棋,在传统的跳棋基础之上,Dove 又延伸出了许多别的玩法.Dove 以一个一维数轴为棋盘下跳棋,总共会移动棋子?? ? 1 次.因为讨厌没有规律,所以Dove 每次只会恰好把棋子向右移动?? 个格子. Cicada 送给了Dove 一个长度为?? 的数列{??},为了表示感谢,Dove 打算以Cicada 送给他

10.2模拟赛总结

10.2 模拟赛总结 T1. 数位dp: 一个非常非常非常非常显然的数位 DP \([L,R] = [1,R]-[1,L-1]\) 所以是分别求两次小于等于某个数字的方案数 \(f(i,j,k)\) 表示从低位数起的第 \(i\) 位,按照规则计算后答案为 \(j\quad (j=0,1)\) \(k\) 表示只考虑后面结尾和 \(lmt\)后面几位 的大小关系 \((k=0,1)\) 考虑第 \(i+1\) 位,算一下新构成的数字并判断下大小就可以了 注意到 \(L,R\) 数据范围特别大,需

10.22 模拟赛

10.22 模拟赛 T1 染色 考虑每个连通块删成一棵树就好了. mmp场上就我路径压缩写炸.... #include<iostream> #define MAXN 200006 using namespace std; int n , m; int fa[MAXN] , siz[MAXN] , book[MAXN] , sz[MAXN]; int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } int main() {

体育成绩统计——20180801模拟赛T3

体育成绩统计 / Score 题目描述 正所谓“无体育,不清华”.为了更好地督促同学们进行体育锻炼,更加科学地对同学们进行评价,五道口体校的老师们在体育成绩的考核上可谓是煞费苦心.然而每到学期期末时,面对海量的原始数据,如何对数据进行处理,得到同学们的体育总评成绩却又成了体育部老师的一大难题. 对于大一的同学们来说,体育课的总评成绩由五部分组成:体育课专项成绩(满分50分).长跑测试成绩(满分20分).“阳光长跑”成绩(满分10分).体质测试成绩(满分10分).“大一专项计划”成绩(满分10分)

10.5模拟赛

这么多模拟赛都没整理,能整理一天算一天吧qaq T1题面 sol:应该不难吧,分别对横坐标和纵坐标取差的绝对值,易知:如果互质就可以看到,否则就不行.然后出题人很毒瘤要用unsigned long long. #include <cstdio> #include <algorithm> using namespace std; long long x1,y1,x2,y2,c1=0,c2=0; unsigned long long x,y; unsigned long long AB

20180520模拟赛T3——chess

[问题描述] 小美很喜欢下象棋. 而且她特别喜欢象棋中的马. 她觉得马的跳跃方式很独特.(以日字格的方式跳跃) 小芳给了小美一张很大的棋盘,这个棋盘是一个无穷的笛卡尔坐标. 一开始\(time=0\)的时候,马在原点.每个时刻马都跳一步. 可是这个坐标图有点残缺,有几个点是不能跳到的. 然后小美很好奇在\(time=[0,K]\)中,马能跳到多少个不同的格子. [输入格式] 从文件chess.in中读入数据. 第一行两个数K,n表示时间上限和残缺的点的数量. 接下来n行,每行一个坐标 xi,yi