首页 > 其他分享 >Top Tree 模板(咕)

Top Tree 模板(咕)

时间:2023-12-03 15:34:54浏览次数:29  
标签:Node return nil rs Top Tree fa ls 模板

Sone1 调不动了,所以是 lg P3690。

写着写着就不知道自己写的是 AAAT 还是 SATT 了,反正能用。

#include <iostream>
#include <vector>
#include <cassert>
#define UP(i,s,e) for(auto i=s; i<e; ++i)
using std::cin; using std::cout;
constexpr int N = 1e5, M = 3e5;
namespace TopTree{ // }{{{
struct Modify_tag{
    int val; bool modi;
    Modify_tag(){}
    Modify_tag(int v, bool t):val(v), modi(t){}
    Modify_tag operator>>=(Modify_tag b){
        if(b.modi) *this = b;
        else val += b.val;
        return *this;
    }
};
enum NodeType{ RAKE, COMPRESS };
using NT = NodeType;
struct Node{
    Node *fa;
    Node *ls, *ms, *rs;
    NT typ;
    int val, hsum, lsum; // heavysum, lightsum
    bool rev;
} nil_, *const nil = &nil_, nds[N*2];
std::vector<int> rubbish; int nodcnt = 0;
Node *nnod(){
    if(!rubbish.empty()){
        Node *p = nds + rubbish.back();
        rubbish.pop_back();
        return p;
    } else {
        return nds + nodcnt++;
    }
}
void erase(Node *x){ rubbish.push_back(x - nds); }
void flip(Node *x){ if(x != nil) x->rev ^= 1; }
void pushrev(Node *x){ 
    if(x == nil || x->typ == RAKE) return;
    if(!x->rev) return;
    std::swap(x->ls, x->rs);
    x->rev ^= 1;
    flip(x->ls);
    flip(x->rs);
}
void pushup(Node *x){
    if(x == nil) return;
    pushrev(x);
    if(x->typ == RAKE){
        x->lsum = x->ls->lsum ^ x->ms->lsum ^ x->rs->lsum;
    } else {
        x->hsum = x->ls->hsum ^ x->rs->hsum ^ x->val;
        x->lsum = x->ls->lsum ^ x->ms->lsum ^ x->rs->lsum ^ x->val;
    }
}
void pushdown(Node *x){ pushrev(x); }
bool nroot(Node *x){ return x == x->fa->ls or x == x->fa->rs; }
bool isrs(Node *x){ return x == x->fa->rs; }
void pushdddd(Node *x){
    if(x == nil) return;
    if(nroot(x)) pushdddd(x->fa);
    pushdown(x);
}
void setfa(Node *x, Node *f, int which){
    if(x != nil) x->fa = f;
    if(which == 0) f->ls = x;
    else if(which == 1) f->rs = x;
    else f->ms = x;
}
void rotate(Node *x){
    if(x == nil || !nroot(x)) return;
    Node *y = x->fa, *z = y->fa;
    if(z != nil){
        if(z->ls == y) z->ls = x;
        else if(z->ms == y) z->ms = x;
        else if(z->rs == y) z->rs = x;
    }
    if(x == y->ls){
        setfa(x->rs, y, 0);
        x->rs = y;
    } else {
        setfa(x->ls, y, 1);
        x->ls = y;
    }
    y->fa = x; x->fa = z;
    pushup(y);
    pushup(x);
}
void splay(Node *x, Node *to = nil){
    if(x == nil) return;
    pushdddd(x);
    for(Node *y; y = x->fa, nroot(x) && y!=to; rotate(x)){
        if(y->fa != to && nroot(y)){
            rotate(isrs(x) ^ isrs(y) ? x : y);
        }
    }
}
void unuse(Node *x){
    if(x == nil) return;
    assert(x->typ == RAKE);
    setfa(x->ms, x->fa, 1);
    x->ms = nil;
    if(x->ls != nil){
        Node *p = x->ls;
        pushdown(p);
        while(p->rs != nil) p = p->rs, pushdown(p);
        splay(p, x);
        setfa(x->rs, p, 1);
        setfa(p, x->fa, 2);
        pushup(p);
        pushup(x->fa);
    } else {
        setfa(x->rs, x->fa, 2);
    }
    erase(x);
}
void splice(Node *x){ 
    if(x == nil) return;
    assert(x->typ == RAKE);
    splay(x);
    Node *y = x->fa;
    splay(y);
    pushdown(x);
    if(y->rs != nil){
        std::swap(x->ms->fa, y->rs->fa);
        std::swap(x->ms, y->rs);
        pushup(x);
    } else {
        unuse(x);
    }
    pushup(y);
}
void access(Node *x){
    if(x == nil) return;
    splay(x);
    if(x->rs != nil){
        Node *y = nnod();
        y->val = 0;
        y->rev = 0;
        y->hsum = y->lsum = 0;
        setfa(x->ms, y, 0);
        setfa(x->rs, y, 2); x->rs = nil;
        setfa(y, x, 2);
        y->rs = nil;
        y->typ = RAKE;
        pushup(y);
        pushup(x);
    }
    Node *p = x;
    while(p->fa != nil){
        splice(p->fa);
        p = p->fa;
        pushup(p);
    }
    splay(x);
}
void mkroot(Node *x){ access(x); flip(x); }
void expose(Node *x, Node *y){ mkroot(x); access(y); }
Node *findrt(Node *x){
    access(x);
    pushdown(x);
    while(x->ls != nil) x = x->ls, pushdown(x);
    splay(x);
    return x;
}
void link(Node *x, Node *y){
    if(findrt(x) == findrt(y)) return;
    access(x);
    mkroot(y);
    setfa(y, x, 1);
    pushup(x);
}
void cut(Node *x, Node *y){
    expose(x, y);
    if(y->ls != x || x->rs != nil) return;
    x->fa = y->ls = nil;
    pushup(y);
}
} // {}}}
namespace m{ // }{{{
constexpr int N = 1e5;
int in, im;
using TopTree::Node;
Node *ndid[N];
void work(){
    cin >> in >> im;
    UP(i, 0, in){
        int x; cin >> x;
        Node *p = TopTree::nnod();
        p->ls = p->ms = p->rs = p->fa = TopTree::nil;
        p->val = p->hsum = p->lsum = x;
        p->typ = TopTree::COMPRESS;
        p->rev = false;
        ndid[i] = p;
    }
    UP(i, 0, im){
        int op, x, y;
        cin >> op >> x >> y;
        switch(op){
            case 0:
                x--, y--;
                if(TopTree::findrt(ndid[x]) != TopTree::findrt(ndid[y])){
                    cout << 0 << '\n';
                } else {
                    TopTree::expose(ndid[x], ndid[y]);
                    cout << ndid[y]->hsum << '\n';
                }
                break;
            case 1:
                x--, y--;
                TopTree::link(ndid[x], ndid[y]);
                break;
            case 2:
                x--, y--;
                TopTree::cut(ndid[x], ndid[y]);
                break;
            case 3:
                x--;
                TopTree::mkroot(ndid[x]);
                ndid[x]->val = y;
                TopTree::pushup(ndid[x]);
                break;
            default:;
        }
    }
}
} // {}}}
int main(){std::ios::sync_with_stdio(0); cin.tie(0); m::work(); return 0;}

标签:Node,return,nil,rs,Top,Tree,fa,ls,模板
From: https://www.cnblogs.com/x383494/p/17873251.html

相关文章

  • RabbitMQ Topic交换机
     代码示例:1.新建两个队列 2.创建交换机,名字叫hmall.topic,类型选择topic 3.hmall.topic交换机绑定第一步的两个队列,绑定过程中填写RoutingKey  4.编写消费者代码监听这两个队列@RabbitListener(queues="topic.queue1")publicvoidlistenQueue05(Str......
  • 在OI类竞赛中经常使用的C++STL模板类
    vector变长数组vector的初始化vector<int>a;//定义一个空的vector,且元素类型为intvector<int>a(n);//定义一个长度为n,元素类型为int的vector,且每个元素都是0vector<int>a(n,x);//定义一个长度为n,元素类型为int,且每个元素都是x的vectorvector<int>b(a);//定义一......
  • 企业级持续集成系列(01):DevTestOps自动化平台设计
     本系列汇总,请查看这里:https://www.cnblogs.com/uncleyong/p/16721826.html 为什么要写企业级持续集成(jenkins+pipeline+k8s)?目前网上自动化持续集成的资料很多,但基本上都是局限于jenkins自由风格的job,结合shell脚本来实现持续集成,这种方式的缺点也很明显:1、构建出问......
  • 二分图最大匹配模板(匈牙利算法)
    二分图最大匹配模板(匈牙利算法)P3386【模板】二分图最大匹配-洛谷|计算机科学教育新生态(luogu.com.cn)structaugment_path{ vector<vector<int>>g; vector<int>pa;//匹配 vector<int>pb; vector<int>vis;//访问 intn,m;//两个点集中的顶......
  • .net core Razor Page TempData不工作,RedirectToPage后无法获取值怎么办?
    问题:.netcore旧项目更新到.netcore8.0后,发现之前的错误反馈信息显示不出来了,经过反复搜索,询问人工智能无果。之前怀疑/测试过:1.新版浏览器chrome访问https://localhost是否限制了Cookie2.浏览器是否受欧盟Cookie法规的要求进行了限制。3.写法错误RazorpageTempData......
  • 软件设计实验 24:模板方法模式
      实验24:模板方法模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解模板方法模式的动机,掌握该模式的结构;2、能够利用模板方法模式解决实际问题。 [实验任务一]:数据库连接对数据库的操作一般包括连接、打开、使用、关闭等步骤,在数据库操作模板类中我......
  • 处理XML--xml.etree.ElementTree
    XML文档的根元素根元素是XML文档中所有其他元素的父元素。它是文档的起点,必须是唯一的<root><!--其他元素和内容--></root>介绍xml信息属性类型意义调用tagstrElement名Element.tagattribdic元素有哪些属性Element.attribtextstr第一个子......
  • QT-对于MVC中典型QTreeView简单使用参考记录
    //创建以ui文件中对应View为载体的model<-此处使用QStandardItemModel(比较常用)QStandardItemModel*model=newQStandardItemModel(ui->treeView);model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("国家")<<QStringLiteral("省份"......
  • 统信UOS/麒麟KYLINOS设置用户模板
    原文链接:统信UOS/麒麟KYLINOS设置用户模板hello,大家好啊,今天给大家带来一篇关于修改用户模板的文章,结合我们之前制作ISO镜像及制作云桌面用户模板的文章,可以一同使用。本篇文章对用户模板的五个方面进行了设置,都是一些很简单的操作,大家可以根据示例进行延伸操作,本文只是提供一种思......
  • 实验四-现代C++标准库与类模板
    1#include<iostream>23usingstd::cout;4usingstd::endl;56classA{7public:8A(intx0,inty0):x{x0},y{y0}{}9voidshow()const{cout<<x<<","<<y<<endl;}10private:11......