NullNone @ 2023-07-17 18:14:11
C++14又紫又红
C++17十分正常
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
struct Node{
int prio, num, ls, rs, siz = 1;
bool laz;
Node(){}
Node(int prio, int num, int ls, int rs, bool laz){
this->prio = prio, this->num = num, this->ls = ls, this->rs = rs, this->laz = laz;
}
inline void print(){cerr << "Node{" << prio << ',' << num << ',' << ls << ',' << rs << ',' << laz << ',' << siz << '}' << endl;}
};
struct Treap{
vector<Node>nodes;
int mem = 0;
int root = -1;
inline int node(){
this->nodes.push_back(Node());
return mem++;
}
inline void check_laz(int cur){
if(this->nodes[cur].laz){
this->nodes[cur].laz = false;
int ls = this->nodes[cur].ls, rs = this->nodes[cur].rs;
swap(this->nodes[cur].ls, this->nodes[cur].rs);
if(ls != -1)
this->nodes[ls].laz ^= 1;
if(rs != -1)
this->nodes[rs].laz ^= 1;
}
}
inline void upd_siz(int cur){
this->nodes[cur].siz = 1;
int ls = this->nodes[cur].ls, rs = this->nodes[cur].rs;
if(ls != -1)
this->nodes[cur].siz += this->nodes[ls].siz;
if(rs != -1)
this->nodes[cur].siz += this->nodes[rs].siz;
}
int build(int lt, int rt){
if(lt == rt){
int cur = this->node();
this->nodes[cur] = Node(this->mem, lt, -1, -1, false);
return cur;
}
int mid = (lt + rt) >> 1;
int cur = this->node();
this->nodes[cur] = Node(this->mem, mid, -1, -1, false);
if(lt < mid)
this->nodes[cur].ls = this->build(lt, mid - 1);
this->nodes[cur].rs = this->build(mid + 1, rt);
this->upd_siz(cur);
return cur;
}
inline void build(int len){this->root = this->build(1, len);}
pair<int, int>split(int cur, int lim){
if(cur == -1)
return make_pair(-1, -1);
this->check_laz(cur);
int lsz = 0;
if(this->nodes[cur].ls != -1)
lsz = this->nodes[this->nodes[cur].ls].siz;
if(lsz < lim){
auto rt = this->split(this->nodes[cur].rs, lim - lsz - 1);
this->nodes[cur].rs = rt.first;
this->upd_siz(cur);
return make_pair(cur, rt.second);
}else{
auto lt = this->split(this->nodes[cur].ls, lim);
this->nodes[cur].ls = lt.second;
this->upd_siz(cur);
return make_pair(lt.first, cur);
}
}
int merge(int a, int b){
if(a == -1) return b;
if(b == -1) return a;
this->check_laz(a);
this->check_laz(b);
if(this->nodes[a].prio < this->nodes[b].prio){
this->nodes[a].rs = this->merge(this->nodes[a].rs, b);
this->upd_siz(a);
return a;
}else{
this->nodes[b].ls = this->merge(a, this->nodes[b].ls);
this->upd_siz(b);
return b;
}
}
inline void reverse(int lt, int rt){
auto m = this->split(this->root, rt);
auto lm = this->split(m.first, lt - 1);
this->nodes[lm.second].laz ^= 1;
this->merge(this->merge(lm.first, lm.second), m.second);
}
void print(int cur){
if(cur == -1)
return;
this->check_laz(cur);
this->print(this->nodes[cur].ls);
cout << this->nodes[cur].num << ' ';
this->print(this->nodes[cur].rs);
}
inline void print(){this->print(this->root); cout << endl;}
}treap;
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
int n, m, l, r;
cin >> n >> m;
treap.build(n);
// treap.print();
while(m--){
cin >> l >> r;
treap.reverse(l, r);
// treap.print();
}
treap.print();
return 0;
}
by CarrotMeow @ 2023-07-17 18:22:10
@NullNone 有 UB?| %%%
by Killer_joke @ 2023-07-17 18:25:12
@NullNone 盲猜是 C++17 额外规定了一些求值顺序。
by NullNone @ 2023-07-17 18:50:59
@StandardManager 请问怎么检查。用脚造小数据不会报错,大数据不好调试 | %%%
by NullNone @ 2023-07-17 18:52:13
@Killer_joke 请问代码中哪些地方容易出现求值顺序的问题
by NullNone @ 2023-07-17 18:54:17
@Killer_joke 我找不到哪里可能有问题,只知道对我来说用动态开点就容易出现离奇问题
by Killer_joke @ 2023-07-17 19:06:29
@NullNone
不建议用vector来写动态开点的数据结构。
一旦发生扩容,会导致之前保存的引用全部失效。容易引发奇怪的问题。
您可以试试在build函数里加一句
nodes.reserve(len);
by NullNone @ 2023-07-17 19:42:33
@Killer_joke 感谢巨佬 %%%