2023-06-04:你的音乐播放器里有 N 首不同的歌,

在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复,

请你为她按如下规则创建一个播放列表,

每首歌至少播放一次,

一首歌只有在其他 K 首歌播放完之后才能再次播放。

返回可以满足要求的播放列表的数量。

由于答案可能非常大,请返回它模 10^9 + 7 的结果。

输入:n = 3, goal = 3, k = 1。

输出:6。

答案2023-06-04:

大体步骤如下:

1.定义常量MOD和LIMIT,分别表示模数和阶乘表的最大值。

2.定义全局变量FAC和INV,分别表示阶乘表和阶乘结果的乘法逆元表。

3.编写init函数,用于初始化FAC和INV数组。在该函数中先将FAC[0]和INV[0]赋值为1,然后使用循环计算FAC[i](i从1到LIMIT)的值,并使用费马小定理倒推计算出INV[i](i从LIMIT到2)的值。

4.编写power函数,用于计算x的n次方并对MOD取模后的结果。

5.编写numMusicPlaylists函数,根据题目要求计算可以满足要求的播放列表数量。该函数中定义三个int64类型变量:cur、ans和sign。cur用于保存当前循环中需要累加到答案中的部分,ans则是最终结果。sign初始为1,在每次循环结束时将其乘以-1来实现交替相加或相减。

6.numMusicPlaylists函数中使用一个for循环遍历i从0到n-k。在每次循环中,首先计算cur = sign * pow(n-k-i, l-k) % MOD。其中pow函数调用了power函数来计算幂次方。

7.然后将cur乘以FAC[n]、INV[i]、INV[n-k-i]并分别对MOD取模,更新cur的值。

8.将cur加到ans中并对MOD取模,最后返回ans的int类型值。

时间复杂度:$O(n2)$,其中n为歌曲数量。需要计算阶乘表和阶乘结果的乘法逆元表,时间复杂度均为O(n)。在numMusicPlaylists函数中使用了一个for循环,循环次数为n-k,每次循环中调用了power函数,时间复杂度为$O(logMOD)$,然后进行了常数次乘、除和取模运算,时间复杂度为O(1)。因此总时间复杂度为$O(n*(n-k)*logMOD)=O(n2*logMOD)$。

空间复杂度:O(n),主要是用来存储阶乘表和阶乘结果的乘法逆元表。

go完整代码如下:

package main

import "fmt"

const MOD int64 = 1000000007
const LIMIT int = 100 // 阶乘表
var FAC [LIMIT + 1]int64 // 阶乘结果的乘法逆元表
var INV [LIMIT + 1]int64 func init() {
FAC[0] = 1
INV[0] = 1
for i := 1; i <= LIMIT; i++ {
FAC[i] = (int64(i) * FAC[i-1]) % MOD
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
INV[LIMIT] = power(FAC[LIMIT], int(MOD-2))
for i := LIMIT; i > 1; i-- {
INV[i-1] = (int64(i) * INV[i]) % MOD
}
} // x的n次方,% mod之后,是多少?
func power(x int64, n int) int64 {
ans := int64(1)
for n > 0 {
if n&1 == 1 {
ans = (ans * x) % MOD
}
x = (x * x) % MOD
n >>= 1
}
return ans
} func numMusicPlaylists(n int, l int, k int) int {
var cur, ans, sign int64 = 0, 0, 1
for i := 0; i <= n-k; i++ {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * -1 -> mod - 1
cur = (sign * power(int64(n-k-i), l-k)) % MOD
cur = (cur * FAC[n]) % MOD
cur = (cur * INV[i]) % MOD
cur = (cur * INV[n-k-i]) % MOD
ans = (ans + cur) % MOD
sign *= -1
}
return int(ans)
} func main() {
n := 3
goal := 3
k := 1
result := numMusicPlaylists(n, goal, k)
fmt.Println(result)
}

rust完整代码如下:

const MOD: i64 = 1_000_000_007;
const LIMIT: usize = 100; // 阶乘表
static mut FAC: [i64; LIMIT + 1] = [0; LIMIT + 1]; // 阶乘结果的乘法逆元表
static mut INV: [i64; LIMIT + 1] = [0; LIMIT + 1]; unsafe fn init() {
INV[0] = 1;
FAC[0] = 1;
for i in 1..=LIMIT {
FAC[i] = ((i as i64) * FAC[i - 1]) % MOD;
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
INV[LIMIT] = power(FAC[LIMIT], (MOD - 2) as i32);
for i in (2..=LIMIT).rev() {
INV[i - 1] = ((i as i64) * INV[i]) % MOD;
}
} // x的n次方,% mod之后,是多少?
fn power(mut x: i64, mut n: i32) -> i64 {
let mut ans = 1;
while n > 0 {
if (n & 1) == 1 {
ans = (ans * x) % MOD;
}
x = (x * x) % MOD;
n >>= 1;
}
ans
} pub fn num_music_playlists(n: i32, goal: i32, k: i32) -> i32 {
unsafe {
init();
let mut cur;
let mut ans = 0;
let mut sign = 1;
for i in 0..=n - k {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * -1 -> mod - 1
cur = (sign * power(n as i64 - k as i64 - i as i64, goal as i32 - k)) % MOD;
cur = (cur * FAC[n as usize]) % MOD;
cur = (cur * INV[i as usize]) % MOD;
cur = (cur * INV[(n - k - i) as usize]) % MOD;
ans = (ans + cur) % MOD;
sign *= -1;
}
ans as i32
}
} fn main() {
let n = 3;
let goal = 3;
let k = 1;
let result = num_music_playlists(n, goal, k);
println!("{}", result);
}

c++完整代码如下:

#include <iostream>
#include <vector> using namespace std; const int MOD = 1000000007;
const int LIMIT = 100; // 阶乘表
vector<int64_t> fac(LIMIT + 1); // 阶乘结果的乘法逆元表
vector<int64_t> inv(LIMIT + 1); int64_t pow2(int64_t x, int n); void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i <= LIMIT; i++) {
fac[i] = ((int64_t)i * fac[i - 1]) % MOD;
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
inv[LIMIT] = pow2(fac[LIMIT], MOD - 2);
for (int i = LIMIT; i > 1; i--) {
inv[i - 1] = ((int64_t)i * inv[i]) % MOD;
}
} // x的n次方,% mod之后,是多少?
int64_t pow2(int64_t x, int n) {
int64_t ans = 1;
while (n > 0) {
if (n & 1) {
ans = (ans * x) % MOD;
}
x = (x * x) % MOD;
n >>= 1;
}
return ans;
} int numMusicPlaylists(int n, int l, int k) {
int64_t cur, ans, sign = 1;
ans = 0; for (int i = 0; i <= n - k; ++i, sign = sign == MOD - 1 ? 1 : MOD - 1) {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * MOD-1 -> mod - 1
cur = (sign * pow2(n - k - i, l - k)) % MOD;
cur = (cur * fac[n]) % MOD;
cur = (cur * inv[i]) % MOD;
cur = (cur * inv[n - k - i]) % MOD;
ans = (ans + cur) % MOD;
} return ans;
} int main() {
init();
int n = 3, goal = 3, k = 1;
int result = numMusicPlaylists(n, goal, k);
cout << result << endl; return 0;
}

c完整代码如下:

#include <stdio.h>
#include <stdint.h> #define MOD 1000000007
#define LIMIT 100 // 阶乘表
int64_t fac[LIMIT + 1]; // 阶乘结果的乘法逆元表
int64_t inv[LIMIT + 1]; int64_t pow2(int64_t x, int n); void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i <= LIMIT; i++) {
fac[i] = ((int64_t)i * fac[i - 1]) % MOD;
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
inv[LIMIT] = pow2(fac[LIMIT], MOD - 2);
for (int i = LIMIT; i > 1; i--) {
inv[i - 1] = ((int64_t)i * inv[i]) % MOD;
}
} // x的n次方,% mod之后,是多少?
int64_t pow2(int64_t x, int n) {
int64_t ans = 1;
while (n > 0) {
if (n & 1) {
ans = (ans * x) % MOD;
}
x = (x * x) % MOD;
n >>= 1;
}
return ans;
} int numMusicPlaylists(int n, int l, int k) {
int64_t cur, ans, sign = 1;
ans = 0; for (int i = 0; i <= n - k; ++i, sign = sign == MOD - 1 ? 1 : MOD - 1) {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * MOD-1 -> mod - 1
cur = (sign * pow2(n - k - i, l - k)) % MOD;
cur = (cur * fac[n]) % MOD;
cur = (cur * inv[i]) % MOD;
cur = (cur * inv[n - k - i]) % MOD;
ans = (ans + cur) % MOD;
} return ans;
} int main() {
init();
int n = 3, goal = 3, k = 1;
int result = numMusicPlaylists(n, goal, k);
printf("%d\n", result); return 0;
}

2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在的更多相关文章

  1. Asp.Net MVC中Aplayer.js音乐播放器的使用

    1.前言: Aplater.js是一款可爱.漂亮的Js音乐播放器,以前就了解过也弄过一些,现在就用mp3的格式来在.Net里面开发.管网 https://aplayer.js.org/ 2.入手: 在 ...

  2. 历上最强的音乐播放器(jetA…

    原文地址:历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉化版)下载作者:盖世天星 历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉 ...

  3. [转载]历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX

    原文地址:历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉化版)下载作者:盖世天星 历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉 ...

  4. Android基于发展Service音乐播放器

    这是一个基于Service组件的音乐播放器,程序的音乐将会由后台的Service组件负责播放,当后台的播放状态改变时,程序将会通过发送广播通知前台Activity更新界面:当用户单击前台Activit ...

  5. Android应用--简、美音乐播放器获取专辑图片(自定义列表适配器)

    Android应用--简.美音乐播放器获取专辑图片(自定义列表适配器) 2013年7月3日简.美音乐播放器开发 第二阶段已增加功能: 1.歌词滚动显示 2.来电监听 3.音量控制 4.左右滑动切换歌词 ...

  6. Android大作业 --音乐播放器

    1.项目成员(本次作业主要对上一次的音乐播放器进行完善) 韦家城 学号:1600802026 班级:161  博客:https://www.cnblogs.com/ln9969cc/ 邓乾尧 学号:1 ...

  7. 推荐美丽的flash网页MP3音乐播放器

    文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/491 在网页制作中.假设想在网页中插入mp3音乐来增添网页的互动感,提升用户体验度,这个时 ...

  8. 搭建rtmp直播流服务之4:videojs和ckPlayer开源播放器二次开发(播放rtmp、hls直播流及普通视频)

    前面几章讲解了使用 nginx-rtmp搭建直播流媒体服务器; ffmpeg推流到nginx-rtmp服务器; java通过命令行调用ffmpeg实现推流服务; 从数据源获取,到使用ffmpeg推流, ...

  9. Movist for Mac(高清媒体播放器)v2.0.7中文特别版

    Movist for Mac中文破解版是目前Mac平台上最好用的视频播放器,功能强大简单好用.movist mac版拥有美观简洁的用户界面,提供多种功能,支持视频解码加速高品质的字幕,全屏幕浏览,是与 ...

  10. 【U3D】播放器设置(PlayerSettings)

    播放器设置 (Player Settings) 播放器设置 (Player Settings) 用于为您要在 Unity 中编译的最终游戏定义各项(特定于平台的)参数.例如,参数中的一些值用于您打开单 ...

随机推荐

  1. Python并发编程——IO模型、阻塞IO、非阻塞IO、多路复用、异步IO、IO模型比较、selectors模块、复习网络和并发知识点

    文章目录 每日测验 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 异步IO(Asy ...

  2. [GXYCTF 2019]BabyUpload

    看到题目是一个文件上传 就先随便传的东西试试,看有什么过滤之类的 上传一个一句话木马,提示后缀名不能为ph 随便上传了带有一句话木马的图片,发现上传成功,但这个图片不能直接利用,要先上传一个.htac ...

  3. idea中常用的快捷键

    IntelliJ IDEA 常用快捷键 一.Ctrl 快捷键 Ctrl + F 在当前文件进行文本查找 (必备) Ctrl + R 在当前文件进行文本替换 (必备) Ctrl + Z 撤销 (必备) ...

  4. MongoDB 中的锁分析

    MongoDB 中的锁 前言 MongoDB 中锁的类型 锁的让渡释放 常见操作使用的锁类型 如果定位 MongoDB 中锁操作 1.查询运行超过20S 的请求 2.批量删除请求大于 20s 的请求 ...

  5. PXE批量网络装机

    PXE高效批量网络装机 系统装机的三种引导方式 1.硬盘 2.光驱(u盘) 3.网络启动 pxe 系统安装过程 加载boot loader Boot Loader 是在操作系统内核运行之前运行的一段小 ...

  6. 聊聊BIO、NIO与AIO的区别(转)

    转自:https://www.cnblogs.com/blackjoyful/p/11534985.html 题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? BIO:Apac ...

  7. VSCODE中无法搜索插件的解决办法

    当前我的使用环境是虚拟机, 如果无法搜索插件但是网络连接是正确的极有可能是代理设置的问题. 解决办法如下: ctrl+, 打开设置 这里填写正确的代理设置.

  8. Kotlin协程系列(一)

    一.协程的定义 最近看了一本有关kotlin协程的书籍,对协程又有了不一样的了解,所以准备写一个关于kotlin协程系列的文章. 言归正传,我们在学习一个新东西的时候,如果连这个东西"是什么 ...

  9. 飞码LowCode前端技术之画布的设计

    简介 本章节从精准定位.分层设计.异步组件.拖拽四个方面分析飞码画布设计. 一.精准定位设计 飞码画布是一个套件,可对外提供画布能力.精准定位有两种情况,一是目标组件无子组件,而是目标组件有子组件. ...

  10. Codeforces Round 905 (Div. 3)

    Codeforces Round 905 (Div. 3) A. Morning 题意:操作:显示,向前走都为一次操作:目标:显示这四个数 思路:0->10,然后依次作差就行 #include ...