首页 > 代码库 > bzoj3159: 决战

bzoj3159: 决战

呀智障选手都快忘了代码怎么打了..


做这道题干啥咧..

GDOI2017D3T4.. dwjshift说很像这道题,然后就去做了..

然后就做了半个月??


简略解法

就是两棵LCT,一棵维护树的结构,一棵维护权值,两棵树在中序遍历上映射,所以维护一下根对根的映射即可


所以要怎么Access..

对于当前点$x$,在把它旋到当前splay的根的时候可以知道它在这棵splay上的排名

然后就去找对应的那棵权值splay的排名就知道映射的是哪个了啊..

然后.. 就没有然后了吧..


下面是代码呀..

#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#define LL long longusing namespace std;const LL Maxn = 50010;struct node {	LL y, next;}a[Maxn*2]; LL first[Maxn], len;LL _max(LL x, LL y) { return x > y ? x : y; }LL _min(LL x, LL y) { return x < y ? x : y; }void ins(LL x, LL y) {	len++;	a[len].y = y;	a[len].next = first[x]; first[x] = len;}LL n, m, r;LL p[Maxn];LL Maxx[Maxn], Minn[Maxn], sum[Maxn], val[Maxn];LL vfa[Maxn], fa[Maxn], sizef[Maxn], sizev[Maxn];LL cf[Maxn][2], cv[Maxn][2];LL revf[Maxn], revv[Maxn], la[Maxn];LL sta[Maxn], tp;char s[10];void dfs(LL x) {	p[x] = x; sizef[x] = sizev[x] = 1;	for(LL k = first[x]; k; k = a[k].next){		LL y = a[k].y;		if(y == fa[x]) continue;		fa[y] = x; vfa[y] = x;		dfs(y);	}}LL rt;/*f*/bool is_rootf(LL x) { return cf[fa[x]][0] != x && cf[fa[x]][1] != x; }void push_downf(LL x) {	if(revf[x]){		swap(cf[x][0], cf[x][1]);		revf[cf[x][0]] ^= 1; revf[cf[x][1]] ^= 1;		revf[x] = 0;	}}void prepf(LL x) {	LL i; tp = 0;	for(i = x; !is_rootf(i); i = fa[i]) sta[++tp] = i;	sta[++tp] = i;	for(i = tp; i >= 1; i--) push_downf(sta[i]);}void updatef(LL x) { sizef[x] = sizef[cf[x][0]]+sizef[cf[x][1]]+1; }void rotatef(LL x) {	LL y = fa[x], z = fa[y], l, r;	if(cf[y][0] == x) l = 0; else l = 1; r = l^1;	if(!is_rootf(y)){ if(cf[z][0] == y) cf[z][0] = x; else cf[z][1] = x; }	fa[x] = z; fa[y] = x; fa[cf[x][r]] = y;	cf[y][l] = cf[x][r]; cf[x][r] = y;	updatef(y);}void splayf(LL x) {	rt = x;	prepf(x);	while(!is_rootf(x)){		LL y = fa[x], z = fa[y];		if(!is_rootf(y)){			if(is_rootf(z)) rt = z;			if((cf[z][0] == y)^(cf[y][0] == x)) rotatef(x);			else rotatef(y);		} else rt = y;		rotatef(x);	}	updatef(x);}/*v*/bool is_rootv(LL x) { return cv[vfa[x]][0] != x && cv[vfa[x]][1] != x; }void push_downv(LL x) {	if(revv[x]){		swap(cv[x][0], cv[x][1]);		revv[cv[x][0]] ^= 1; revv[cv[x][1]] ^= 1;		revv[x] = 0;	}	if(la[x] > 0){		if(cv[x][0] > 0){			sum[cv[x][0]] += sizev[cv[x][0]]*la[x]; val[cv[x][0]] += la[x];			Maxx[cv[x][0]] += la[x];			Minn[cv[x][0]] += la[x];		la[cv[x][0]] += la[x];		} if(cv[x][1] > 0){			sum[cv[x][1]] += sizev[cv[x][1]]*la[x]; val[cv[x][1]] += la[x];			Maxx[cv[x][1]] += la[x];			Minn[cv[x][1]] += la[x];			la[cv[x][1]] += la[x];		}		la[x] = 0;	}}void prepv(LL x) {	LL i; tp = 0;	for(i = x; !is_rootv(i); i = vfa[i]) sta[++tp] = i;	sta[++tp] = i;	for(i = tp; i >= 1; i--) push_downv(sta[i]);}void updatev(LL x) {	Maxx[x] = _max(Maxx[cv[x][0]], _max(Maxx[cv[x][1]], val[x]));	Minn[x] = _min(Minn[cv[x][0]], _min(Minn[cv[x][1]], val[x]));	sum[x] = sum[cv[x][0]]+sum[cv[x][1]]+val[x];	sizev[x] = sizev[cv[x][0]]+sizev[cv[x][1]]+1;}void rotatev(LL x) {	LL y = vfa[x], z = vfa[y], l, r;	if(cv[y][0] == x) l = 0; else l = 1; r = l^1;	if(!is_rootv(y)){ if(cv[z][0] == y) cv[z][0] = x; else cv[z][1] = x; }	vfa[x] = z; vfa[y] = x; vfa[cv[x][r]] = y;	cv[y][l] = cv[x][r]; cv[x][r] = y;	updatev(y);}void splayv(LL x) {	prepv(x);	while(!is_rootv(x)){		LL y = vfa[x], z = vfa[y];		if(!is_rootv(y)){			if((cv[z][0] == y)^(cv[y][0] == x)) rotatev(x);			else rotatev(y);		}		rotatev(x);	}	updatev(x);}LL find_rank(LL x, LL p) {	push_downv(x);	if(sizev[cv[x][0]]+1 == p) return x;	if(sizev[cv[x][0]] >= p) return find_rank(cv[x][0], p);	else return find_rank(cv[x][1], p-sizev[cv[x][0]]-1);}void splay(LL x) {	splayf(x);	LL o = find_rank(p[rt], sizef[cf[x][0]]+1);	splayv(o);	p[x] = o;}void access(LL x) {	LL tf = 0, tv = 0;	while(x){		splay(x);		LL o = p[x];		p[cf[x][1]] = cv[o][1];		cf[x][1] = tf;		cv[o][1] = tv;		if(tv) vfa[tv] = o;		tv = o;		tf = x;		x = fa[x];	}}void make_root(LL x) { access(x); splay(x); revf[x] ^= 1; revv[p[x]] ^= 1; }void getchain(LL x, LL y) { make_root(x); access(y); splay(y); }LL getsum(LL x, LL y) { getchain(x, y); return sum[p[y]]; }LL getmin(LL x, LL y) { getchain(x, y); return Minn[p[y]]; }LL getmax(LL x, LL y) { getchain(x, y); return Maxx[p[y]]; }void add(LL x, LL y, LL c) { getchain(x, y); sum[p[y]] += sizev[p[y]]*c; val[p[y]] += c; Maxx[p[y]] += c; Minn[p[y]] += c; la[p[y]] += c; }void invert(LL x, LL y) { getchain(x, y); revv[p[y]] ^= 1; }int main() {	LL i, j, k;	Maxx[0] = -0x7fffffff; Minn[0] = 0x7fffffff;	scanf("%lld%lld%lld", &n, &m, &r);	for(i = 1; i < n; i++){		LL x, y;		scanf("%lld%lld", &x, &y);		ins(x, y); ins(y, x);	}	dfs(r);	for(i = 1; i <= m; i++){		scanf("%s", s+1);		if(s[1] == ‘I‘ && s[3] == ‘c‘){			LL x, y, c;			scanf("%lld%lld%lld", &x, &y, &c);			add(x, y, c);		} else if(s[1] == ‘S‘){			LL x, y;			scanf("%lld%lld", &x, &y);			printf("%lld\n", getsum(x, y));		} else if(s[1] == ‘M‘ && s[2] == ‘a‘){			LL x, y;			scanf("%lld%lld", &x, &y);			printf("%lld\n", getmax(x, y));		} else if(s[1] == ‘M‘){			LL x, y;			scanf("%lld%lld", &x, &y);			printf("%lld\n", getmin(x, y));		} else {			LL x, y;			scanf("%lld%lld", &x, &y);			invert(x, y);		}	}	return 0;}

 

bzoj3159: 决战