P3690 非旋 LCT 求调
  • 板块题目总版
  • 楼主x383494
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/8/4 22:00
  • 上次更新2023/11/3 05:51:37
查看原帖
P3690 非旋 LCT 求调
747335
x383494楼主2023/8/4 22:00

RT,从这学的

#include <iostream>
#include <random>
#define UP(i,s,e) for(auto i=s; i<e; ++i)
std::mt19937 rdna(0x383494);
std::uniform_real_distribution<> RAnd_(0, 1);
#define Rnd() RAnd_(rdna)
namespace LCT{ // }{{{
struct Node{
	Node *ls, *rs, *fa;
	int lisiz, alsiz; // light_siz, all_siz
	int val, sum;
	bool rev;
	Node();
} nil_, *nil = &nil_;
Node::Node(){ fa = ls = rs = nil; }
bool isrs(Node *x){ return x == x->fa->rs; }
bool nroot(Node *x){ return x == x->fa->ls || x == x->fa->rs; }
void flip(Node *x){ x->rev ^= 1; }
void pushup(Node *x){ 
	x->sum = x->ls->sum ^ x->rs->sum ^ x->val; 
	x->alsiz = 1 + x->ls->alsiz + x->rs->alsiz + x->lisiz;
}
void pushuuuu(Node *x){
	pushup(x);
	if(nroot(x)) pushuuuu(x->fa);
}
void pushdown(Node *x){
	if(!x->rev) return;
	if(x->ls != nil) flip(x->ls);
	if(x->rs != nil) flip(x->rs);
	std::swap(x->ls, x->rs);
}
void pushdddd(Node *x){
	if(nroot(x)) pushdddd(x->fa);
	pushdown(x);
}
Node *merge(Node *sm, Node *bg){
	if(sm == nil || bg == nil) return sm == nil ? bg : sm;
	if(Rnd()*(sm->alsiz + bg->alsiz) < sm->alsiz){
		pushdown(sm);
		sm->rs = merge(sm->rs, bg);
		bg->fa = sm;
		pushup(sm);
		return sm;
	} else {
		pushdown(bg);
		bg->ls = merge(sm, bg->ls);
		sm->fa = bg;
		pushup(bg);
		return bg;
	}
}
Node* splitl(Node *x, Node *&sm, Node *&bg){ // [0, x]:sm, (x, r): bg, return light-fa
	pushdddd(x);
	Node *f = x->fa;
	sm = x, bg = x->rs;
	x->rs = nil;
	pushup(x);
	while(nroot(x)){
		if(isrs(x)){
			f->ls = bg;
			bg->fa = f;
			bg = f;
		} else {
			f->rs = sm;
			sm->fa = f;
			sm = f;
		}
		pushup(f);
		x = f;
		f = f->fa;
	}
	//sm->fa = bg->fa = nil;
	return f;
}
Node *access(Node *x){ // return root of x
	Node *ret = nil;
	while(x != nil){
		Node *sm, *bg;
		Node *top = splitl(x, sm, bg);
		if(bg != nil) bg->fa = x;
		x->lisiz -= bg->alsiz;
		x->lisiz += ret->alsiz;
		pushuuuu(x);
		ret = merge(sm, ret);
		x = top;
		ret->fa = x;
	}
	return ret;
}
Node *getroot(Node *x){
	while(nroot(x)) x=x->fa;
	return x;
}
void mkroot(Node *x){ flip(access(x)); }
void link(Node *x, Node *y){
	mkroot(x);
	Node *r = getroot(x);
	r->fa = y;
	y->lisiz += r->alsiz;
	access(y);
	pushuuuu(y);
}
void cut(Node *x, Node *y){
	mkroot(x);
	access(y);
	Node *tmp1, *tmp2;
	splitl(x, tmp1, tmp2);
}
int query(Node *x, Node *y){
	mkroot(x);
	Node *rt = access(y);
	return rt->sum;
}
} // {}}}
namespace m{ // }{{{
constexpr int N = 1e5, M = 3e5;
using std::cin;
using std::cout;
using namespace LCT;
Node nds[N];
int in, im;
void work(){
	cin >> in >> im;
	UP(i, 0, in) cin >> nds[i].val;
	UP(i, 0, im){
		int op, x, y;
		cin >> op >> x >> y;
		x--, y--;
		if(op == 0){
			cout << query(nds+x, nds+y) << '\n';
		} else if(op == 1){
			link(nds+x, nds+y);
		} else if(op == 2){
			cut(nds+x, nds+y);
		} else {
			y++;
			nds[x].val = y;
			pushup(nds+x);
		}
	}
}
} // {}}}
int main(){ std::ios::sync_with_stdio(0); std::cin.tie(0); m::work(); return 0;}

2023/8/4 22:00
加载中...