[bzoj3153] sone1 AC纪念

本文详细记录了作者解决bzoj3153题的过程,并分享了最终的AC代码。该题涉及复杂的数据结构操作和算法优化。

bzoj3153 sone1


历时两天A掉此题,特作纪念。


代码
#include <bits/stdc++.h>

typedef long long LL;

#define FOR(i, a, b) for (int i = (a), i##_END_ = (b); i <= i##_END_; i++)
#define DNF(i, a, b) for (int i = (a), i##_END_ = (b); i >= i##_END_; i--)

template <typename Tp> void in(Tp &x) {
    char ch = getchar(), f = 1; x = 0;
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    x *= f;
}

template <typename Tp> bool chkmax(Tp &x, Tp y) {return x > y ? 0 : (x=y,1);}
template <typename Tp> bool chkmin(Tp &x, Tp y) {return x < y ? 0 : (x=y,1);}
template <typename Tp> Tp Max(Tp x, Tp y) {return x > y ? x : y;}
template <typename Tp> Tp Min(Tp x, Tp y) {return x < y ? x : y;}

const int MAXN = 200010;

struct Tag {
    int k, b;

    Tag(int k = 1, int b = 0): k(k), b(b) {} 

    Tag run(const Tag &another) const {
        return Tag(k * another.k, b * another.k + another.b);
    }
};

struct Data {
    int minx, maxx, sum, sz;

    Data(int sz = 0, int minx = 0x3f3f3f3f, int maxx = -0x3f3f3f3f, int sum = 0)
        :minx(minx), maxx(maxx), sum(sum), sz(sz) {}

    Data run(const Tag &another) const {
        if (minx > maxx) return *this;

        Data ret;
        ret.sum = sum * another.k + sz * another.b;
        ret.sz = sz;

        if (another.k < 0) {
            ret.minx = another.k * maxx + another.b;
            ret.maxx = another.k * minx + another.b;
        }

        else {
            ret.maxx = another.k * maxx + another.b;
            ret.minx = another.k * minx + another.b;
        }

        return ret;
    }

    Data run(const Data &another) const {
        Data ret;
        if (minx > maxx) return another;
        if (another.minx > another.minx) return *this;
        ret.sz = sz + another.sz;
        ret.sum = sum + another.sum;
        ret.minx = Min(minx, another.minx);
        ret.maxx = Max(maxx, another.maxx);
        return ret;
    }
};

struct Node {
    bool inner;
    bool is_rev;
    Node *ch[4], *fa;
    Tag tag_chain, tag_sub;
    Data data_chain, data_sub, data_all, my;

    void pushdown();
    void update();

    void add();
    void del();

    void push();
    void pushO();
    void pushI();

    void splayO();
    void splayI();
    void rotate(int);
    void access(bool=false);

    bool is_top_out();
    bool is_top_inn();

    void makerot();

    void push_rev();
    void push_tag_chain(Tag);
    void push_tag_sub(Tag);
} *to[MAXN];

int n, m, rt;
int input[MAXN][2], w[MAXN];

int debug(Node *x)
{
    FOR(i, 1, n) if (x == to[i]) return i;
    return 0;
}

void Node::pushO()
{
    assert(!inner);
    if (!is_top_out()) fa -> pushO();
    pushdown();
}

void Node::pushI()
{
    //if (!inner) return;
    assert(inner);
    if (!is_top_inn()) fa -> pushI();
    pushdown();
}

void initialize()
{
    FOR(i, 1, n) {
        to[i] = new Node;
        to[i] -> ch[0] = to[i] -> ch[1] =
            to[i] -> ch[2] = to[i] -> ch[3] = NULL;
        to[i] -> fa = NULL;
        to[i] -> inner = false;
        to[i] -> is_rev = false;
        to[i] -> tag_chain = to[i] -> tag_sub = Tag();
        to[i] -> data_chain = to[i] -> data_sub = Data();
        to[i] -> my = Data(1, w[i], w[i], w[i]);
        to[i] -> data_all =
            to[i] -> my.run(to[i] -> data_chain).run(to[i] -> data_sub);
    }
}

void Node::push()
{
    if (fa) fa -> push(); pushdown();
}

bool Node::is_top_out()
{
    return !fa || fa -> ch[0] != this && fa -> ch[1] != this;
}

bool Node::is_top_inn()
{
    //printf("%d %d\n", inner, fa);
    //printf("%d\n", fa != NULL);
    return !fa -> inner;
}

void Node::add()
{
    Node *tmp = fa;
    while (tmp -> ch[3] != NULL && (tmp -> inner || tmp == fa)) {
        tmp -> pushdown();
        tmp = tmp -> ch[3];
    }

    if (tmp != fa) assert(!tmp -> inner);

    if (tmp == fa) tmp -> ch[3] = this;
    else {
        tmp -> fa -> ch[3] = new Node;

        Node *&x = tmp -> fa -> ch[3];
        x -> inner = true;
        x -> is_rev = false;
        x -> fa = tmp -> fa;
        x -> ch[0] = x -> ch[1] = NULL;
        x -> ch[2] = tmp; x -> ch[3] = this;

        tmp -> fa = fa = x;

        Node *tep = x;
        while (tep -> inner) {
            tep -> update(); tep = tep -> fa;
        }

        x -> splayI();
    }
}

void Node::del()
{
    int t = fa -> ch[2] == this ? 2 : 3;

    if (fa -> ch[t] != this) {
        assert(fa -> ch[t] == this);
    }

    if (fa -> inner) {
//      Node *tt = fa;
        fa -> pushI();

        Node *bro = fa -> ch[t ^ 1];
        bro -> fa = fa -> fa;
        int tt = bro -> fa -> ch[2] == fa ? 2 : 3;

        assert(bro -> fa -> ch[tt] == fa);

        bro -> fa -> ch[tt] = bro;
        Node *tep = bro -> fa;
        while (tep -> inner) {
            tep -> update(); tep = tep -> fa;
        }
        if (bro -> fa -> inner)
            bro -> fa -> splayI();
        delete fa;
    }

    else {
        fa -> pushdown();
        fa -> ch[t] = NULL;
    }
}

//不负责update,只负责pushdown
void Node::access(bool is)
{
    push();

    splayO(); pushdown();
    if (ch[1] != NULL) ch[1] -> add();

    ch[1] = NULL; update();

    Node *x = this;

    while (x -> fa != NULL) {
        Node *tmp = x -> fa;
        while (tmp -> inner) tmp = tmp -> fa;

        if (!is) x -> del();
        else is = false;

        //while (tmp -> inner) tmp = tmp -> fa;

        tmp -> splayO(); tmp -> pushdown();
        if (tmp -> ch[1] != NULL) tmp -> ch[1] -> add();

        x -> fa = tmp;
        tmp -> ch[1] = x; tmp -> update();

        x = tmp;
    }
}

void Node::rotate(int dir)
{
    Node *pa = fa; fa = pa -> fa;

    if (fa != NULL) {
        int t = (fa -> ch[0] == pa ? 0 :
                 (fa -> ch[1] == pa ? 1 : (fa -> ch[2] == pa ? 2 : 3)));
        fa -> ch[t] = this;
    }

    pa -> ch[dir] = ch[dir ^ 1];
    if (ch[dir ^ 1] != NULL) ch[dir ^ 1] -> fa = pa;
    ch[dir ^ 1] = pa; pa -> fa = this;

    pa -> update(); update();
}

void Node::splayO()
{
    assert(!inner);
    pushO();
    while (!is_top_out()) {
        int t1 = fa -> ch[0] == this ? 0 : 1;
        if (!fa -> is_top_out()) {
            int t2 = fa -> fa -> ch[0] == fa ? 0 : 1;
            if (t1 == t2) fa -> rotate(t1), rotate(t1);
            else rotate(t1), rotate(t2);
        }
        else rotate(t1);
    }
}

void Node::splayI()
{
    assert(inner);
    pushI();
    while (!is_top_inn()) {
        int t1 = fa -> ch[2] == this ? 2 : 3;
        if (!fa -> is_top_inn()) {
            int t2 = fa -> fa -> ch[2] == fa ? 2 : 3;
            if (t1 == t2) fa -> rotate(t1), rotate(t1);
            else rotate(t1), rotate(t2);
        }
        else rotate(t1);
    }
}

void Node::push_rev()
{
    is_rev ^= 1;
    std::swap(ch[0], ch[1]);
}

void Node::push_tag_chain(Tag x)
{
    tag_chain = tag_chain.run(x);

    my = my.run(x);
    data_chain = data_chain.run(x);
    data_all = my.run(data_sub).run(data_chain);
}

void Node::push_tag_sub(Tag x)
{
    tag_sub = tag_sub.run(x);
    //tag_chain = tag_chain.run(x);

    //my = my.run(x);
    data_sub = data_sub.run(x);
    //data_chain = data_chain.run(x);
    data_all = my.run(data_sub).run(data_chain);
}

void Node::update()
{
    data_sub = Data();
    if (ch[0] != NULL) data_sub = data_sub.run(ch[0] -> data_sub);
    if (ch[1] != NULL) data_sub = data_sub.run(ch[1] -> data_sub);
    if (ch[2] != NULL) data_sub = data_sub.run(ch[2] -> data_all);
    if (ch[3] != NULL) data_sub = data_sub.run(ch[3] -> data_all);

    data_chain = Data();
    if (ch[0] != NULL)
        data_chain = data_chain.run(ch[0] -> data_chain).run(ch[0] -> my);
    if (ch[1] != NULL)
        data_chain = data_chain.run(ch[1] -> data_chain).run(ch[1] -> my);

    data_all = my.run(data_sub).run(data_chain);
}

void Node::pushdown()
{
    if (is_rev) {
        if (ch[0] != NULL) ch[0] -> push_rev();
        if (ch[1] != NULL) ch[1] -> push_rev();
        is_rev = false;
    }

    {
        Tag &tag = tag_chain;

        if (tag.k != 1 || tag.b != 0) {
            if (ch[0] != NULL) ch[0] -> push_tag_chain(tag);
            if (ch[1] != NULL) ch[1] -> push_tag_chain(tag);
            tag = Tag(1, 0);
        }
    }

    {
        Tag &tag = tag_sub;

        if (tag.k != 1 || tag.b != 0) {
            if (ch[0] != NULL) ch[0] -> push_tag_sub(tag);
            if (ch[1] != NULL) ch[1] -> push_tag_sub(tag);

            if (ch[2] != NULL) {
                ch[2] -> push_tag_chain(tag);
                ch[2] -> push_tag_sub(tag);
            }
            if (ch[3] != NULL) {
                ch[3] -> push_tag_chain(tag);
                ch[3] -> push_tag_sub(tag);
            }

            tag = Tag(1, 0);
        }
    }
}

void Node::makerot()
{
    access(); splayO(); push_rev();
}

void link(Node *x, Node *y)
{
    y -> access(); y -> pushdown();
    x -> makerot(); x -> fa = y; x -> access(true);
}

void cut(Node *x, Node *y)
{
    x -> makerot(); y -> access(); y -> splayO();
    y -> pushdown(); x -> fa = y -> ch[0] = NULL; y -> update();
}

Node *find_rot(Node *x)
{
    x -> access(); x -> splayO(); x -> pushdown();
    while (x -> ch[0] != NULL) {
        x = x -> ch[0]; x -> pushdown();
    }
    return x;
}

int main()
{
    in(n); in(m);

    FOR(i, 1, n - 1) {
        in(input[i][0]); in(input[i][1]); 
    }

    FOR(i, 1, n) in(w[i]);

    initialize();

    in(rt);

    FOR(i, 1, n - 1) {
        link(to[input[i][0]], to[input[i][1]]);
    }

    FOR(i, 1, m) {
        int tp; in(tp);

        to[rt] -> makerot();

        //FOR(i, 1, n)
        //  to[i] -> access();

        //to[rt] -> splayO();

        //printf("%d\n", to[rt] -> data_all.sz);

        if (tp == 0) {
            int x, y; in(x); in(y);

            to[x] -> access(); to[x] -> splayO();

            if (x == rt) {
                to[x] -> push_tag_chain(Tag(0, y));
                to[x] -> push_tag_sub(Tag(0, y));
            }
            else {
                to[x] -> my = to[x] -> my.run(Tag(0, y));
                if (to[x] -> ch[3] != NULL) {
                    to[x] -> ch[3] -> push_tag_chain(Tag(0, y));
                    to[x] -> ch[3] -> push_tag_sub(Tag(0, y));
                }
                if (to[x] -> ch[2] != NULL) {
                    to[x] -> ch[2] -> push_tag_chain(Tag(0, y));
                    to[x] -> ch[2] -> push_tag_sub(Tag(0, y));
                }
                to[x] -> update();
            }
        }

        else if (tp == 1) {
            int x; in(x); rt = x;
        }

        else if (tp == 2) {
            int x, y, z; in(x); in(y); in(z);
            to[x] -> makerot(); to[y] -> access(); to[y] -> splayO();
            to[y] -> push_tag_chain(Tag(0, z));
        }

        else if (tp == 3) {
            int x; in(x); to[x] -> access();

            Data ret = Data();
            if (to[x] -> ch[2] != NULL) ret = ret.run(to[x] -> ch[2] -> data_all);
            if (to[x] -> ch[3] != NULL) ret = ret.run(to[x] -> ch[3] -> data_all);
            ret = ret.run(to[x] -> my);

            printf("%d\n", ret.minx);
        }

        else if (tp == 4) {
            int x; in(x); to[x] -> access();

            Data ret = Data();
            if (to[x] -> ch[2] != NULL) ret = ret.run(to[x] -> ch[2] -> data_all);
            if (to[x] -> ch[3] != NULL) ret = ret.run(to[x] -> ch[3] -> data_all);
            ret = ret.run(to[x] -> my);

            printf("%d\n", ret.maxx);
        }

        else if (tp == 5) {
            int x, y; in(x); in(y);

            to[x] -> access(); to[x] -> splayO();

            if (x == rt) {
                to[x] -> push_tag_chain(Tag(1, y));
                to[x] -> push_tag_sub(Tag(1, y));
            }
            else {
                to[x] -> my = to[x] -> my.run(Tag(1, y));
                if (to[x] -> ch[2] != NULL) {
                    to[x] -> ch[2] -> push_tag_chain(Tag(1, y));
                    to[x] -> ch[2] -> push_tag_sub(Tag(1, y));
                }
                if (to[x] -> ch[3] != NULL) {
                    to[x] -> ch[3] -> push_tag_chain(Tag(1, y));
                    to[x] -> ch[3] -> push_tag_sub(Tag(1, y));
                }
                to[x] -> update();
            }
        }

        else if (tp == 6) {
            int x, y, z; in(x); in(y); in(z);
            to[x] -> makerot(); to[y] -> access(); to[y] -> splayO();
            to[y] -> push_tag_chain(Tag(1, z));
        }

        else if (tp == 7) {
            int x, y; in(x); in(y);
            to[x] -> makerot(); to[y] -> access(); to[y] -> splayO();
            printf("%d\n", to[y] -> my.run(to[y] -> data_chain).minx);
        }

        else if (tp == 8) {
            int x, y; in(x); in(y);
            to[x] -> makerot(); to[y] -> access(); to[y] -> splayO();
            printf("%d\n", to[y] -> my.run(to[y] -> data_chain).maxx);
        }

        else if (tp == 9) {
            int x, y; in(x); in(y);

            to[y] -> access(); to[x] -> access();
            to[x] -> splayO(); to[x] -> pushdown();

            if (to[x] -> ch[0] == NULL) continue;
            else {
                to[y] -> access(); to[y] -> splayO();

                Node *tmp = to[x];
                while (!tmp -> is_top_out()) tmp = tmp -> fa;

                if (tmp == to[y]) continue;

                to[x] -> access(); to[x] -> splayO(); to[x] -> pushdown();
                tmp = to[x] -> ch[0]; tmp -> pushdown();
                while (tmp -> ch[1] != NULL) {tmp = tmp -> ch[1]; tmp -> pushdown();}

                cut(to[x], tmp); link(to[x], to[y]);
            }
        }

        else if (tp == 10) {
            int x, y; in(x); in(y);
            to[x] -> makerot(); to[y] -> access(); to[y] -> splayO();
            printf("%d\n", to[y] -> my.run(to[y] -> data_chain).sum);
        }

        else if (tp == 11) {
            int x; in(x); to[x] -> access(); //to[x] -> splayO();

            Data ret = Data();
            if (to[x] -> ch[2] != NULL) ret = ret.run(to[x] -> ch[2] -> data_all);
            if (to[x] -> ch[3] != NULL) ret = ret.run(to[x] -> ch[3] -> data_all);
            ret = ret.run(to[x] -> my);

            printf("%d\n", ret.sum);
        }
    }

    return 0;
}
内容概要:本文档围绕“虚拟电厂的多时间尺度调度”展开,重点研究在考虑储能系统容量衰减的前提下,如何整合发电侧与多用户负荷的灵活性,实现优化调度。该研究属于顶级SCI论文复现项目,采用Matlab进行代码实现,涵盖日前调度与日【顶级SCI复现】虚拟电厂的多时间尺度调度:在考虑储能系统容量衰减的同时,整合发电与多用户负荷的灵活性研究(Matlab代码实现)内调度两个时间尺度,旨在提升虚拟电厂对可再生能源波动性和负荷不确定性的应对能力。文档还列举了多个相关科研方向与技术资源,包括Copula理论用于光伏功率预测、鲸鱼算法优化深度学习模型(如WOA-CNN-LSTM)、风光互补制氢合成氨系统优化、电力系统稳定性分析等,展示了其在电力系统优化、新能源调度、储能管理等领域的广泛应用价值。; 适合人群:具备电力系统、能源管理、自动化或相关专业背景的研究生、博士生及科研人员,熟悉Matlab编程与优化建模工具(如YALMIP、Cplex)者更佳;同时适用于从事虚拟电厂、微电网、综合能源系统等领域工程实践的技术人员。; 使用场景及目标:① 复现高水平SCI论文中的虚拟电厂多时间尺度调度模型,掌握考虑储能衰减的建模方法;② 学习并应用先进优化算法(如智能算法、ADMM、纳什博弈)解决能源系统调度问题;③ 拓展至风光氢储耦合系统、电热综合能源系统等复杂场景的容量配置与运行优化研究;④ 获取完整的Matlab代码资源与仿真案例,支撑科研论文写作与项目开发。; 阅读建议:建议按目录顺序系统浏览,优先理解虚拟电厂调度的整体架构与数学模型,再结合提供的Matlab代码进行调试与仿真;对于涉及的概率预测、优化求解、系统建模等内容,应参考相应文献深化理论基础,注重模型假设与实际工程的衔接,提升科研创新能力。
这个是完整源码 python实现 Django,echarts 【python毕业设计】基于Python的农产品可视化系统(Django+echarts) 源码+论文+sql脚本 完整版 数据库是mysql 本研究提出了一种基于Python的农产品可视化系统,结合Django框架和ECharts库,旨在为农产品数据的展示和分析提供便捷、高效的解决方案。系统通过Django框架构建后端服务,使用本研究提出了一种基于Python的农产品可视化系统,结合Django框架和ECharts库,旨在为农产品数据的展示和分析提供便捷、高效的解决方案。系统通过Django框架构建后端服务,使用ECharts实现前端数据可视化展示,能够直观地呈现农产品的产量、销售情况、价格波动等多维度数据。通过数据处理与图表绘制相结合,用户可以实时查看农产品相关信息,并进行趋势分析、对比分析等操作,从而为农业生产决策、市场分析等提供数据支持。此外,系统还具有良好的扩展性,能够根据实际需求灵活添加新的功能模块,如数据导入导出、用户管理等。实验结果表明,ECharts实现前端数据可视化展示,能够直观地呈现农产品的产量、销售情况、价格波动等多维度数据。通过数据处理与图表本研究提出了一种基于Python的农产品可视化系统,结合Django框架和ECharts库,旨在为农产品数据的展示和分析提供便捷绘制本研究提出了一种基于Python的农产品可视化系统,结合Django框架和ECharts库,旨在为农产品数据的展示和分析提供便捷、高效的解决方案。系统通过Django框架从而为农业生产决策、市场分析等提供数据支持。此外,系统还具有良好的扩展性,能够根据实际需求灵活添加新的功能模块,如数据导入导出、用户管理等。实验结果表明,该系统在提高农产品数据管理效率、优化决策支持系统等方面具有显著优势,具有较高的应用价值和推广前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值