代码随想录算法训练营Day64|拓扑排序(卡码网117)、dijkstra朴素版

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

拓扑排序

117. 软件构建 (kamacoder.com)

拓扑排序简单的说是将一个有向图转为线性的排序。

它将图中的所有结点排序成一个线性序列,使得对于任何的边uv,结点u在序列中都出现在结点v之前,这样的序列满足图中所有的前驱-后继关系。

拓扑排序通常用于任务调度、项目计划、编译依赖分析等场景,其中活动或任务之间存在依赖关系,需要确定一个合理的执行顺序。

拓扑排序的算法步骤如下:

  1. 选择一个没有前驱的结点(即入度为0的结点),将其加入到拓扑排序的序列中,并从图中删除该节点及其所有出边。
  2. 重复步骤1,直到所有的结点都被加入拓扑排序序列中或者途中不再存在无前驱的结点。
  3. 如果所有的结点都被加入序列中,则完成了拓扑排序;若图中还存在结点,则说明图中存在环,无法进行拓扑排序。

        由于拓扑排序的结果可能不唯一,当图中存在多个入度为0的结点,可以任意选择一个结点进行删除。

在实际应用中,拓扑排序通常和深度优先搜索或广度优先搜素结合使用。例如,使用广度优先搜索(拓扑排序的广度优先搜索实现通常被称为Kahn算法)进行拓扑排序的算法流程如下:

  1. 计算所有节点的入度:遍历图中的所有节点,计算每个节点的入度(即有多少边指向该节点)。

  2. 初始化队列:创建一个空队列,将所有入度为0的节点加入队列。这些节点是没有前置依赖的节点,可以开始执行。

  3. 处理队列:只要队列不为空,就重复以下步骤:

    • 从队列中取出一个节点(称为当前节点),并将其添加到拓扑排序的结果序列中。
    • 减少当前节点的所有出边指向的节点的入度(因为这些节点的依赖减少了)。
    • 如果某个节点的入度在减少后变为0,则将其加入队列,因为它现在没有前置依赖了。
  4. 检查是否有未处理的节点:当队列为空时,如果所有的节点都已经添加到拓扑排序的结果序列中,则拓扑排序成功完成。如果还有节点未添加到结果序列中,则说明图中存在环,因此无法进行拓扑排序。

伪代码

拓扑排序(图 G):
    初始化入度为0的队列 Q
    初始化拓扑排序的结果序列 L

    // 计算所有节点的入度
    对于每个节点 v in G:
        v.入度 = G 中指向 v 的边的数量
        如果 v.入度 == 0:
            Q.enqueue(v)

    // 处理队列
    当 Q 不为空时:
        当前节点 u = Q.dequeue()
        L.add(u)  // 将 u 添加到拓扑排序的结果序列中

        // 减少所有出边的目标节点的入度
        对于每个节点 v,其中存在边 u -> v:
            v.入度 = v.入度 - 1
            如果 v.入度 == 0:
                Q.enqueue(v)

    // 检查是否所有节点都已处理
    如果 L 中的节点数量不等于 G 中的节点数量:
        返回 "图 G 包含环,无法进行拓扑排序"
    否则:
        返回 L 作为拓扑排序的结果序列

C++代码参考代码随想录代码随想录 (programmercarl.com)

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;

int main() {
    int N, M; // N个文件存在M条依赖关系
    cin >> N >> M;
    vector<int> inDegree(N, 0); // 记录每个点的入度
    unordered_map<int, vector<int>> umap;

    // 读取M条依赖关系
    for (int i = 0; i < M; i++) {
        int s, t;
        cin >> s >> t;
        // t依赖于s,因此t的入度加1
        inDegree[t]++;
        umap[s].push_back(t);
    }

    queue<int> Queue;
    // 将所有入度为0的节点加入队列
    for (int i = 0; i < N; i++) {
        if (inDegree[i] == 0)
            Queue.push(i);
    }

    vector<int> path; // 存储拓扑排序结果
    while (!Queue.empty()) {
        int cur = Queue.front();
        Queue.pop();
        path.push_back(cur);

        // 遍历当前节点的所有后继节点
        for (int next : umap[cur]) {
            inDegree[next]--;
            if (inDegree[next] == 0)
                Queue.push(next);
        }
    }

    // 检查是否所有的节点都被处理了
    if (path.size() == N) {
        for (int i = 0; i < N - 1; i++) {
            cout << path[i] << " ";
        }
        cout << path[N - 1];
    } else {
        // 如果不是所有的节点都被处理,说明存在环
        cout << -1 << endl;
    }

    return 0;
}

在时间复杂度上,初始化入度数组O(N),读取依赖关系并构建邻接表O(M)(M条依赖关系),将入度为0结点加入队列,O(N),BFS的时间复杂度为O(N+M)(每个结点最多访问一次,每个结点被加入队列后移除,每条边会被访问一次来减少相邻结点的入度)时间复杂度为O(N+M)

空间复杂度 入度数组O(N),邻接表最差情况下O(N^2),队列和路径数组都为O(N),最差情况下空间复杂度为O(N^2),但实际应用中,若图比较稀疏,则空间复杂度为O(M+N)。

dijkstra

47. 参加科学大会(第六期模拟笔试) (kamacoder.com)

        Dijkatra算法是一种著名的图搜索算法,它用于在加权图中找到从一源节点到其余所有结点的最短路径。

算法步骤:

  1. 初始化:需要一个最短路径估计的容器(优先队列,通常是最小堆)存储所有结点及其当前的最短路径估计值,除源节点设置为0外,将所有结点的最短路径估计值设置为无穷大。
  2. 访问源结点:将源结点加入优先队列。
  3. 循环处理队列:当优先队列非空时,重复以下步骤:

    从优先队列中取出具有最小估计值的节点,称为当前节点。

    对于当前节点的每个邻接节点,执行以下操作:

    1. 计算通过当前节点到达邻接节点的路径长度。
    2. 如果这个路径长度比已知的最短路径估计值更短,则更新邻接节点的最短路径估计值,并更新它的前驱节点为当前节点。
    3. 将邻接节点及其新的最短路径估计值加入优先队列。 
  4. 标记完成:当一个结点从优先队列取出时,意味着它的最短路径已经确定,可以将其标记为完成。
  5. 构建最短路径树:当算法结束时,可以从源结点开始,通过每个结点的前驱结点信息,构造出从源结点到所有其他结点的最短路径树。

需要注意的几个点:

  • Dijkstra算法不能处理带有负权边的图,因为在有负权边的图中,可能存在一条路径,其总权重随着经过的边数增加而减少,导致无法正确找到最短路径。
  • Dijkstra算法的时间复杂度为O(V^2),V为图中结点的数量,使用优先队列可以优化到O(E+VlogV),E为边的数量、
  • Dijkstra可以用于有向图和无向图。

代码随想录 (programmercarl.com)

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

int main() {
    int N, M; // N个文件存在M条依赖关系
    cin >> N >> M;
    vector<vector<int>> grid(N+1, vector<int>(N+1, INT_MAX)); // 创建一个N+1xN+1的二维数组,用于存储节点之间的权重,初始化为INT_MAX
    int v1, v2, val;
    for (int i = 0; i < M; i++) { // 读取M条依赖关系
        cin >> v1 >> v2 >> val; // 读取两个节点v1和v2以及它们之间的权重val
        grid[v1][v2] = val; // 更新权重矩阵,表示v1到v2有边,权重为val
    }
    int start = 1; // 定义起始节点为1
    int end = N; // 定义目标节点为N
    vector<int> minDist(N+1, INT_MAX); // 创建一个长度为N+1的数组,用于存储从起始节点到其他节点的最短路径估计值,初始化为INT_MAX
    vector<int> visited(N+1, 0); // 创建一个长度为N+1的数组,用于标记节点是否被访问过,0表示未访问,1表示已访问
    minDist[start] = 0; // 起始节点到自身的最短路径为0

    for (int i = 0; i <= N; i++) { // 循环,找到未访问的最短路径节点
        int minVal = INT_MAX; // 初始化最小值为INT_MAX
        int cur = 1; // 初始化当前节点为1
        for (int v = 1; v <= N; v++) { // 遍历所有节点,找到未访问且最短路径估计值最小的节点
            if (!visited[v] && minDist[v] < minVal) { // 如果节点v未访问且最短路径估计值小于minVal
                minVal = minDist[v]; // 更新最小值
                cur = v; // 更新当前节点为v
            }
        }
        visited[cur] = 1; // 标记当前节点为已访问
        for (int v = 1; v <= N; v++) { // 遍历所有节点,更新从当前节点出发到其他节点的最短路径估计值
            if (!visited[v] && grid[cur][v] != INT_MAX && minDist[cur] + grid[cur][v] < minDist[v]) {
                // 如果节点v未访问,且当前节点到节点v有边,且通过当前节点到达v的路径更短
                minDist[v] = minDist[cur] + grid[cur][v]; // 更新节点v的最短路径估计值
            }
        }
    }

    if (minDist[end] == INT_MAX) // 如果目标节点的最短路径估计值仍然是INT_MAX,表示没有路径到达目标节点
        cout << -1 << endl; // 输出-1
    else
        cout << minDist[end] << endl; // 否则输出从起始节点到目标节点的最短路径长度
    return 0;
}

算法的时间复杂度为O(N^2),空间复杂度这里也是O(N^2)(没有用上最小堆等优先队列)

Flatten 层的深度理解与运用 阅读详情

相关推荐

从Microchip SDK到STM32实战:手把手教你移植LAN9252 EtherCAT从站驱动(含EEPROM配置避坑)

本文详细介绍了如何将Microchip SDK中的LAN9252 EtherCAT从站驱动移植到STM32F407平台,包括FSMC接口配置、中断处理适配和EEPROM配置等关键步骤。通过实战指南和避坑技巧,帮助开发者快速实现高性能EtherCAT从站设备的开发,适用于工业自动化领域。

weixin_29197835的博客 446

笔记:代码随想录算法训练营day64:拓扑排序精讲、dijkstra(朴素版)精讲

要先处理被依赖的文件。两步曲:找到入度为0的节点,加入结果;删除入度为0的节点(具体操作为将其通向的节点的入度数减一,从而可以判断删除之后的节点了)还是要看一下模拟过程,感觉贪心有一个特别精妙的点在于,直觉上感觉是每一次都选择最短路径可能会错过其他路径,但代码实现起来其实是都考虑到了。相对于prim算法 minDist表示 节点到最小生成树的最小距离,dijksta算法minDist表示 节点到源点的最小距离。整个过程使用广度优先搜索完成,毕竟每一次要记录该节点通向的所有节点,与广度优先搜索非常契合。

jingjingjing1111的博客 332

ArcGIS实战:手把手教你用DEM和灾害点数据,5步搞定地质灾害风险区划图

本文详细介绍了使用ArcGIS进行地质灾害风险评估的完整流程,从DEM和灾害点数据出发,通过五步标准化操作生成专业风险区划图。重点讲解了信息量模型的应用,帮助读者掌握GIS技术在地质灾害易发性评价中的实践方法,提升风险评估效率与准确性。

weixin_30696427的博客 423

【代码随想录】【算法训练营】【第64天】 [卡码117]软件构建 [卡码47]参加科学大会

思路及算法思维,指路。题目来自。day 64,周三,继续ding~

day day up 877

CMOS sensor 基础

NA

m0_72053187的博客 1657

别再手动配网了!用安信可PB-02模组+PHY Mesh App,5分钟搞定蓝牙Mesh智能灯群控

本文详细介绍了如何使用安信可PB-02模组和PHY Mesh App快速搭建蓝牙Mesh智能灯群控系统。通过5分钟的硬件连接和固件烧录,用户可实现多灯分组控制、场景切换及地理围栏等高级功能,显著提升智能家居部署效率。方案特别适合需要快速实现灯光群控的场景。

weixin_28675839的博客 416

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 15

Halcon实战:5分钟搞定自定义直线卡尺工具(附完整代码下载)

本文详细介绍了如何使用Halcon快速开发自定义直线卡尺工具,通过交互式ROI绘制、边缘检测和直线拟合三个核心函数,实现高效工业视觉检测。文章包含完整代码下载,帮助开发者在5分钟内掌握这一实用工具的开发技巧,提升直线检测的精度和效率。

perl8的博客 248

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 437

【第1章>第5节】SOM自组织映射网络的理论学习与MATLAB仿真

自组织映射网络(Self-Organizing Map,SOM)是一种无监督学习的人工神经网络,由芬兰学者Teuvo Kohonen于1981年提出,也被称为Kohonen网络。它的主要功能是将高维输入数据映射到低维(通常是二维)的离散网格上,同时保持输入数据的拓扑结构,即相邻的输入数据在映射后的网格上也相邻。

FPGA/MATLAB学习教程/源码/项目合作开发 400

Python实现PDB文件预处理

蛋白质结构研究依赖PDB文件存储的三维结构数据,但原始文件常含无关的水分子、离子和非标准残基等干扰信息。本文介绍了一个基于BioPython的Python预处理脚本,可自动清理PDB文件,主要功能包括:1)移除短于阈值的蛋白质链;2)过滤非标准氨基酸;3)可选保留水分子和金属离子。该脚本逻辑清晰,支持批量处理,能显著提升结构比对、分子对接等分析前的数据准备效率,为后续生物信息学研究提供更纯净的结构数据基础。

Protein Designer的博客 567

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 362

uniapp:解决微信小程序包体积超过2M的优化方案+详解分包问题,编译小程序体积大于2M不能上传和预览提示体积太大的处理教程,uniApp微信小程序主包过大问题如何解决(排查可疑点+分包+最小改动)

uniapp微信小程序开发,如何解决打包太大无法预览发布的问题,uniApp微信小程序包体积超过2M的优化方法,uni-app打包微信小程序主包超2M终极解决方案,使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法,UniApp开发的微信小程序主包过大问题及解决方案 编译小程序时Node-modules被打入主包,小程序体积大于2M不能上传和预览,怎么处理,解决微信小程序主包太大问题,微信小程序中主包和分包过大,详解分包问题,uni-app 微信小程序发布时,主包超

✅ 精选推荐文章 5066

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 77

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

AI和大模型—从克里金算法说开去

克里金算法源于矿业勘探,通过空间自相关性实现稀疏数据下的最优预测,核心优势在于不确定性量化。在AI大模型中,其等价于高斯过程,广泛应用于超参数优化、小样本建模与推理调度。尽管面临计算复杂度高、核函数选择难等问题,通过稀疏化、分治法与低秩近似可有效优化。该方法在降低训练成本、提升泛化能力及减少幻觉方面表现突出,尤其适用于高维、高成本的智能系统优化,具有重要借鉴价值。

fpcc的专栏 602

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 176

算法札记:几何分布在算法题UVA1262的运用

集卡问题求解核心:将集齐n种优惠券的过程分为n个阶段,每个阶段期望购买次数为 $ \frac{n}{k} $(k为剩余种类数),总期望为 $ n \cdot H_n $(调和数)。通过自洽方程推导单阶段期望,无需几何分布或无穷级数,逻辑清晰且适用于大一水平。例如,n=5时期望约11.42,非5。题目要求以带分数形式输出精确结果,算法上需累加分数并化简。

Keven_11的博客 308

不同的二叉搜索树

互不相同的二叉搜索树的种数,以 j (1<=j<=i)为头节点,左子树是 j-1 个数,右子树就是 i - (j - 1) -1 = i - j个数。所以dp[3] = dp[0] * dp[2] + dp[1] * dp[1] + dp[2] * dp[0]头1 = 左子树0节点 * 右子树2节点,二叉搜索树就是排序树,左子树<根节点<右子树,左右子树也满足左子树<根节点<右子树。头2 = 左子树1节点 * 右子树1节点。所以dp[i] += dp[j-1] * dp[i-j]个节点组成且节点值从。

qq_44721738的博客 150

SSL证书选RSA还是ECDSA:公钥算法、CA签名与兼容性怎么核对

申请SSL证书时,RSA和ECDSA该怎么选?先分清站点公钥算法、CA签名算法和TLS实际兼容性,再用隔离OpenSSL实验读取两类材料,核对申请、续期和部署交接,避免只看Signature Algorithm就选错。

谁呀!的博客 381

固件开发岗算法

背景:嵌入式固件岗,偏爱手写库函数、位运算、数组基础算法。

2502_90352018的博客 109

从曲线到储层:Techlog/KAPPA 全流程算法、UltraLAB 选型与本地 AI 部署实战

以高频 CPU 保证交互,以充足内存承载多井与多任务,以 NVMe 打通项目和知识库 I/O,再按本地模型、上下文与并发配置 GPU。对 UltraLAB 用户而言,更合理的采购方式是带着真实项目做选型:一组典型井、一套完整解释模板、一个目标大模型、一次多人并发测试。用实测结果确定配置,才能把预算转化为解释效率,而不是闲置算力。软件模块、操作系统与许可条件以厂商当前正式说明为准;硬件建议需结合项目实测。AI 输出只能作为辅助证据,不能替代岩石物理与油藏工程专业审核。

wdf8088的博客 161

【Deep-OC-SORT 01】多轨迹算法Deep-OC-SORT源码分析

本工程基于Deep-OC-SORT核心模块,重构并适配了EmbeddingComputer(外观特征提取)、CMCComputer(相机运动补偿)与OCSort(主跟踪器)三类。前者实现整框/网格模式的特征提取与L2归一化;后者通过稀疏光流或SIFT匹配估计仿射变换,补偿相机运动;主跟踪器融合IoU、外观相似度与方向一致性,支持模块开关与自定义组件,实现高效多目标跟踪。

Jayson 博客 330

C++ 标准库算法全景指南

本文系统梳理C++标准库<algorithm>与<numeric>中100+算法,按功能分为非修改、修改、排序、二分查找、归并、堆、极值、字典序、排列及数值操作十大类,涵盖典型用法与时间复杂度。结合C++20范围(ranges)与投影特性,实现更简洁高效的代码。

sss123ddd的博客 232

高速公路无人机巡检系统:场景、算法与部署方案

高速公路巡检的工程矛盾,不在“能不能飞到”,而在“端侧算力、时延约束与精度要求三者之间如何分配”。路面病害要求毫米级识别,但高速动态成像与运动模糊压制了单帧精度;交通事件要求秒级推送,但隧道与峡谷的通信盲区切断了云端链路;桥梁梁底的无卫星信号环境,则把自主定位的难度推到了GNSS失效的边界。本文从“端—边—云”三级协同的工程逻辑出发,拆解路面病害、交通事件、桥梁结构三类场景下算法与部署的实际取舍,结合重庆绕城高速、广西六宾高速、南京6G低空巡检等公开数据,给出可复用的系统设计参考。

THJS优快云的博客 192

Consistent-Point半监督人群计数算法详解

本文首次指出并量化了点定位半监督人群计数中伪点的位置不一致与类别不一致问题(Mean-Teacher baseline 甚至不如只用标注数据),并给出两个极简正交模块——PA 用"被匹配的伪点与其邻近提议点定位相似"的洞察做空间平均,以 1/K 方差收缩稳住位置;IUC 用分类得分做实例级加权,压低决策边界附近模糊伪点的监督强度。两模块零推理开销、只引入一个超参 λ,在 5 数据集 × 3 标注比例的 15 个定位设置上全部 SOTA,并在 CPS 框架上验证泛化性,说明"伪标签一致性"是点定位半监督范式中

Keep_Trying_Go的博客 320

算法日常・每日刷题--<动态规划>41

给定两个字符串text1和text2,求其最长公共子序列长度。使用动态规划,定义dp[i][j]为text1前i个字符与text2前j个字符的最长公共子序列长度。若字符相等,则dp[i][j] = dp[i-1][j-1] + 1;否则取舍弃一方的最大值:dp[i][j] = max(dp[i-1][j], dp[i][j-1])。最终返回dp[m][n]。时间复杂度O(mn),空间复杂度O(mn)。

2503_92261635的博客 134

嵌入式 AI 智能相机怎么选?从算力、算法架构、部署方式深度对比

在工业自动化视觉检测场景中,嵌入式 AI 智能相机正在逐步替代传统 “工业相机 + 上位机工控机” 的方案。但市面上产品参数繁杂,很多工程师选型时容易被纸面算力、宣传卖点误导。本文从**持续算力性能、算法架构设计、现场部署模式**三个核心维度,梳理嵌入式视觉设备不同技术路线的差异、适用边界与落地痛点,为机器视觉工程师、自动化集成商、产线技改负责人提供可落地的选型参考。

VisionDataLab的博客 291
上一篇: 代码随想录算法训练营Day63|最小生成树算法prim和kruskal、kama 53.寻宝
下一篇: 代码随想录算法训练营Day65|dijkstra堆优化版、Bellman_ford算法
viaNoir
博客等级 码龄10年 535粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值