P4577 [FJOI2018] DP + 线段树合并

博客详细介绍了如何解决FJOI2018竞赛中的领导集团问题,即寻找树上满足特定条件的最大节点子集。该问题采用了类似于LIS(最长递增子序列)的思路,利用动态开点的权值线段树来维护以每个节点为根的子树中的信息。通过DFS遍历树并进行线段树的合并操作,最终找到满足条件的最大子集。文章内容深入浅出,适合对算法和数据结构感兴趣的读者。
题意

传送门 P4577 [FJOI2018]领导集团问题

题解

求树上最大节点子集,若子集中 j j j i i i 的子孙节点,则有 w j ≥ w i w_j\geq w_i wjwi

参考 L I S LIS LIS 问题的求解思路,设 d p [ i ] [ j ] dp[i][j] dp[i][j] 为以 i i i 为根的子树上规模为 j j j 的满足条件节点子集中最小点权的最大值,此时 d p [ i ] dp[i] dp[i] 的规模,即 j j j 的最大值为答案。

考虑如何合并子树信息,以 k k k 为根的子树上的 d p [ k ] [ j ] dp[k][j] dp[k][j] 显然是随 j j j 增加递减的,两颗子树 k , w k,w k,w 的节点间没有限制,可以任意合并,那么对 d p [ k ] , d p [ w ] dp[k],dp[w] dp[k],dp[w] 归并排序即可。最后考虑如何处理 i i i 的信息,设子树合并的信息为 d p [ i ′ ] dp[i'] dp[i] w i w_i wi 可以以满足 d p [ i ′ ] [ j ] , d p [ i ′ ] [ j ] ≥ w i dp[i'][j],dp[i'][j]\geq w_i dp[i][j],dp[i][j]wi 对应的节点为子孙节点,那么将 w i w_i wi 替换 d p [ i ′ ] dp[i'] dp[i] 中满足 d p [ i ′ ] [ j ] < w i dp[i'][j]<w_i dp[i][j]<wi 的最大值,此时得到 d p [ i ] dp[i] dp[i]

对每个节点 i i i 建立一颗动态开点的权值线段树代替 d p [ i ] dp[i] dp[i],支持单点修改,区间查询;同时可以二分查找每次子树根节点需要替换的节点,设 [ 0 , w i ) [0,w_i) [0,wi) 的点数和为 s s s,满足条件的节点为恰好满足 [ 0 , j ] [0,j] [0,j] 的点数和等于 s s s 的节点 j j j。对领导树进行 D F S DFS DFS,采用线段树合并维护 d p [ i ] dp[i] dp[i] 的归并过程。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005, maxt = 19 * maxn;
struct node
{
#define ls(x) tree[x].ls
#define rs(x) tree[x].rs
#define sum(x) tree[x].sum
    int ls, rs, sum;
} tree[maxt];
int N, W[maxn], nw, sw[maxn];
int num, rt[maxn];
int tot, head[maxn], to[maxn], nxt[maxn];

void insert(int x, int d, int &p, int l, int r)
{
    if (!p)
        p = ++num;
    if (r - l == 1)
    {
        sum(p) += d;
        return;
    }
    int m = (l + r) >> 1;
    x < m ? insert(x, d, ls(p), l, m) : insert(x, d, rs(p), m, r);
    sum(p) = sum(ls(p)) + sum(rs(p));
}

int merge(int p, int q, int l, int r)
{
    if (!p || !q)
        return p + q;
    if (r - l == 1)
    {
        sum(p) += sum(q);
        return p;
    }
    int m = (l + r) >> 1;
    ls(p) = merge(ls(p), ls(q), l, m), rs(p) = merge(rs(p), rs(q), m, r);
    sum(p) = sum(ls(p)) + sum(rs(p));
    return p;
}

void change(int x, int d, int p, int l, int r)
{
    if (r - l == 1)
    {
        sum(p) += d;
        return;
    }
    int m = (l + r) >> 1;
    x < m ? change(x, d, ls(p), l, m) : change(x, d, rs(p), m, r);
    sum(p) = sum(ls(p)) + sum(rs(p));
}

int ask(int a, int b, int p, int l, int r)
{
    if (r <= a || b <= l)
        return 0;
    if (a <= l && r <= b)
        return sum(p);
    int m = (l + r) >> 1;
    return ask(a, b, ls(p), l, m) + ask(a, b, rs(p), m, r);
}

int find(int x, int p, int l, int r)
{
    if (r - l == 1)
        return l;
    int m = (l + r) >> 1;
    return sum(ls(p)) >= x ? find(x, ls(p), l, m) : find(x - sum(ls(p)), rs(p), m, r);
}

void dfs(int x)
{
    for (int i = head[x], y; i; i = nxt[i])
        y = to[i], dfs(y), rt[x] = merge(rt[x], rt[y], 0, nw);
    int t = ask(0, W[x], rt[x], 0, nw), z;
    if (t)
        z = find(t, rt[x], 0, nw), change(z, -1, rt[x], 0, nw);
}

inline void add(int x, int y) { to[++tot] = y, nxt[tot] = head[x], head[x] = tot; }

int main()
{
    scanf("%d", &N);
    for (int i = 1; i <= N; ++i)
        scanf("%d", W + i), sw[i] = W[i];
    sort(sw + 1, sw + N + 1);
    nw = unique(sw + 1, sw + N + 1) - (sw + 1);
    for (int i = 1; i <= N; ++i)
        W[i] = lower_bound(sw + 1, sw + nw + 1, W[i]) - (sw + 1);
    for (int i = 1; i <= N; ++i)
        insert(W[i], 1, rt[i], 0, nw);
    for (int i = 1, v; i < N; ++i)
        scanf("%d", &v), add(v, i + 1);
    dfs(1), printf("%d\n", sum(rt[1]));
    return 0;
}
内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识和Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统和负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
内容概要:本文档聚焦于“直流电机双闭环控制Matlab仿真”,系统阐述了基于Matlab/Simulink平台实现直流电机双闭环控制系统(主要包括速度环与电流环)的设计与仿真全过程。通过构建直流电机的数学模型,结合PI控制器进行调控,实现对电机转速和电枢电流的高精度动态控制,验证控制策略的稳定性与响应性能。文档详细介绍了仿真模型的搭建流程、关键参数的整定方法、系统动态波形的分析手段以及仿真结果的有效性验证,体现了经典自动控制理论在实际电机系统中的工程应用,是电机控制与电力电子技术相结合的典型研究案例。; 适合人群:具备自动控制原理、电机与拖动基础、电力电子技术和Matlab/Simulink仿真能力的电气工程、自动化、机电一体化等专业的本科生、研究生及从事电机驱动系统研发的工程技术人员。; 使用场景及目标:①作为高校课程设计或实验教学材料,帮助学生深入理解双闭环调速系统的工作机理与工程实现;②服务于科研项目,为新型电机控制算法(如滑模、模糊PID等)的开发与性能对比提供基础仿真验证平台;③作为工业界产品前期设计的仿真工具,用于评估不同控制策略在动态响应、抗干扰能力和稳态精度方面的可行性。; 阅读建议:建议读者在学习过程中紧密结合自动控制理论知识,亲手在Simulink环境中搭建完整的双闭环仿真模型,通过反复调整PI控制器的比例与积分参数,观察并分析转速、电流的阶跃响应曲线,从而深刻理解反馈控制的本质、系统稳定性条件以及参数整定对动态性能的影响,进而掌握电机控制系统的设计精髓。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值