Comet OJ #contest14 D.转转的数据结构题(珂朵莉树)

本文介绍了一种利用珂朵莉树和线段树解决区间更新问题的算法,通过离线处理和按右端点排序的查询,有效地处理了大量区间修改和查询操作。

题目:https://cometoj.com/contest/73/problem/D?problem_id=4120

由于有“将一段区间全部变成v”这一操作,考虑使用珂朵莉树维护。

将所有查询离线按右端点排序,在每个查询询问前,将1到R的操作全部做完,然后使用线段树/树状数组查询大于当前询问的L的操作产生的贡献。

在珂朵莉树的节点中记录一下当前节点是由第几次操作产生,assigan时消除上次的贡献,加入现在的贡献,即可维护操作产生的区间和。

ac代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 5e5 + 5;

int n, m, q;
ll ans[maxn];

struct op {
    int l, r;
    ll v;
} a[maxn];

struct query {
    int l, r, id;

    friend bool operator<(const query &a, const query &b) {
        return a.r < b.r;
    }
} b[maxn];

struct node {
    int l, r, id;
    ll v;

    friend bool operator<(const node &a, const node &b) {
        return a.l < b.l;
    }
};

ll t[maxn << 2];

void update(int rt, int l, int r, int pos, ll val) {
    if (l == r) {
        t[rt] += val;
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid) {
        update(rt << 1, l, mid, pos, val);
    } else {
        update(rt << 1 | 1, mid + 1, r, pos, val);
    }
    t[rt] = t[rt << 1] + t[rt << 1 | 1];
}

ll query(int rt, int l, int r, int L, int R) {
    if (l >= L && r <= R) {
        return t[rt];
    }
    int mid = (l + r) >> 1;
    ll ans = 0;
    if (L <= mid) {
        ans += query(rt << 1, l, mid, L, R);
    }
    if (R > mid) {
        ans += query(rt << 1 | 1, mid + 1, r, L, R);
    }
    return ans;
}

set<node> cot;

void init(int l, int r, int v) {
    cot.clear();
    cot.insert({l, r, 0, v});
}

auto spilt(int x) {
    if (x > n) {
        return cot.end();
    }
    auto it = --cot.upper_bound({x, 0, 0, 0});
    if (it->l == x) {
        return it;
    }
    int l = it->l, r = it->r, v = it->v, id = it->id;
    cot.erase(it);
    cot.insert({l, x - 1, id, v});
    return cot.insert({x, r, id, v}).first;
}

void assign(int l, int r, ll v, int id) {
    //先split右端点,再split左端点
    auto itr = spilt(r + 1), itl = spilt(l);
    for (; itl != itr;) {
        auto j = itl;
        ++itl;
        update(1, 1, m, j->id, -1LL * (j->r - j->l + 1) * j->v);
        cot.erase(j);
    }
    cot.insert({l, r, id, v});
    update(1, 1, m, id, 1LL * (r - l + 1) * v);
}

int main() {
    scanf("%d%d%d", &m, &n, &q);
    for (int i = 1; i <= m; ++i) {
        scanf("%d%d%lld", &a[i].l, &a[i].r, &a[i].v);
    }
    for (int i = 1; i <= q; ++i) {
        scanf("%d%d", &b[i].l, &b[i].r);
        b[i].id = i;
    }
    sort(b + 1, b + q + 1);

    init(1, n, 0);
    for (int i = 1; i <= q; ++i) {
        for (int j = b[i - 1].r + 1; j <= b[i].r; ++j) {
            assign(a[j].l, a[j].r, a[j].v, j);
        }
        ans[b[i].id] = query(1, 1, m, b[i].l, m);
    }
    for (int i = 1; i <= q; ++i) {
        printf("%lld\n", ans[i]);
    }
    return 0;
}
/*
1 500000 1
1 500000 2000000000
1 1
 */
内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值