第一次写LCT写挂了,求助大佬
查看原帖
第一次写LCT写挂了,求助大佬
234913
GBLoi楼主2020/6/6 20:05
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#define LL long long
#define rint register int
#define RG register 
using namespace std;
namespace FastIO
{
const int _SIZE = (1 << 21) + 1;
char ibuf[_SIZE],obuf[_SIZE];
char *iS,*iT;
char c;
char qu[55];
char *oS=obuf,*oT=oS+_SIZE-1;
bool _sign=false;
int qr;
// getchar
#define gc() (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, _SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
// print the remaining part
inline void flush() 
{
    fwrite(obuf,1,oS-obuf,stdout);
    oS=obuf;
    return;
}
// putchar
inline void putc(const char &x) 
{
    *oS++=x;
    if(oS==oT)
        flush();
    return;
}
inline char getc()
{
	return gc();
}
// input a signed integer
template <class T>
inline void read(T &x) 
{
	x=0;
	_sign=false;
    for (c=gc();c<'0'||c>'9';c=gc())
        if (c=='-')
            _sign=true;
    for (;c>='0'&&c<='9';c=gc()) 
		x=(x<<1)+(x<<3)+(c&15);
    x=(_sign) ? (~x+1) : x;
    return;
}
// print a signed integer
template <class T>
inline void print(T x) {
    if (!x) {
    	putc('0');
    	return;
	}
    if (x<0)
        putc('-'),x=~x+1;
    while(x) qu[++qr]=x%10+'0',x/=10;
    while(qr) putc(qu[qr--]);
    return;
}
// no need to call flush at the end manually!
struct Flusher_ 
{
    ~Flusher_() { flush(); }
}io_flusher_;
}  // namespace io
using FastIO::read;
using FastIO::print;
using FastIO::putc;
using FastIO::getc;
//=======================================
const int N=1e5+5;
namespace LCT
{
struct Node *nul;
Node *merge(Node *x,Node *y);
struct Node
{
	Node *lc,*rc;
	Node *fa;
	int val;
	int pri;
	int sum;
	bool rev;
	Node(Node *L,Node *R,int V) : lc(L),rc(R),val(V) { rev=false,pri=rand(),fa=nul; }
	Node() { lc=rc=nul; }
	inline void pushup()
 	{
 		sum=val;
 		if(lc!=nul)
		 	sum^=lc->sum;
		if(rc!=nul) 
			sum^=rc->sum; 
 		return;
	}
	inline bool ntroot() { return (fa==nul) ? false : (fa->lc==this||fa->rc==this); }
	inline void save()
	{	
		Node *now=this;
		for(;now->ntroot();now->pushup());
		now->pushup();
	}
	inline void Addrev() 
	{
		rev^=1;
		swap(lc,rc);
	}
	inline void pushdown()
	{
		if(rev==false) 
			return;
		lc->Addrev();
		rc->Addrev();
		rev=false;
		return;
	}
	inline void preview() { if(ntroot()) fa->preview(); pushdown(); } 
	inline Node* root() 
	{
		if(this==nul) return nul;
		Node *now=this;
		while(now->ntroot()) 
			now=now->fa;
		return now;	
	}
	inline Node* split(Node *&x,Node *&y)
	{
		preview();
		Node *now=this;
		x=now; y=now->rc;
		x->rc=nul;
		x->pushup();
		for(;now->fa!=nul;now=now->fa) {
			if(now==now->fa->lc) {
				now->fa->lc=y;
				y->fa=now->fa;
				y=now->fa;
			}
			else if(now==now->fa->lc) {
				now->fa->rc=x;
				x->fa=now->fa;
				x=now->fa;
			}
			else break;
			now->fa->pushup();
		}
		if(fa!=nul)
			now->fa->pushup();
		if(x!=nul) x->fa=nul;
		if(y!=nul) y->fa=nul;
		return now;
	}
	inline Node* access()
	{
		Node *now=this,*res,*root;
		Node *x,*y;
		for(;now!=nul;now=res->fa=root) {
			root=now->split(x,y);
			now->save();
			if(y!=nul)
				y->fa=now;
			res=merge(x,res);
		}
		return res;
	}
	inline void make_root() { access()->Addrev(); }
}*t[N];
Node *merge(Node *x,Node *y)
{
	if(x==nul||y==nul) return (x==nul) ? y : x;
	if(x->pri>y->pri) {
		x->rc=merge(x->rc,y);
		x->rc->fa=x;
		x->pushup();
		return x;
	}
	else {
		y->lc=merge(x,y->lc);
		y->lc->fa=y;
		y->pushup();
		return y;
	}
}
inline Node* findroot(Node *now)
{
	now=now->access();
	while(now->lc!=nul) {
		now->pushdown();
		now=now->lc;
	}
	return now;
}
inline void link(Node *x,Node *y)
{
	x->make_root();
	Node *r=x->root();
	y->access();
	if(y->root()==r) 
		return;
	r->fa=y;
	return;
}
inline Node* pull(Node *x,Node *y)
{
	x->make_root();
	return y->access();
}
inline void cut(Node *x,Node *y)
{
	x->make_root();
	if(findroot(y)==x&&y->fa==x&&y->lc==nul) {
		x->rc=y->fa=nul;
		x->pushup();
	}
	return;
}
}
using namespace LCT;
int n,m;
int main()
{
//	freopen("1.in","r",stdin);
	srand((unsigned)time(0));
	rint i,j;
	int x,y,z,opt;
	read(n); read(m);
	for(i=1;i<=n;i++) {
		read(x);
		t[i]=new Node(nul,nul,x);
		t[i]->pushup();
	}
	while(m--) {
		read(opt); read(x); read(y);
		if(opt==0) print(pull(t[x],t[y])->sum);
		else if(opt==1) link(t[x],t[y]);
		else if(opt==2) cut(t[x],t[y]);
		else if(opt==3) t[x]->val=y,t[x]->save();
	}
	return 0;
}

2020/6/6 20:05
加载中...