zoukankan      html  css  js  c++  java
  • bzoj3159: 决战

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


    做这道题干啥咧..

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

    然后就做了半个月??


    简略解法

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


    所以要怎么Access..

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

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

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


    下面是代码呀..

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #define LL long long
    using 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
    ", getsum(x, y));
    		} else if(s[1] == 'M' && s[2] == 'a'){
    			LL x, y;
    			scanf("%lld%lld", &x, &y);
    			printf("%lld
    ", getmax(x, y));
    		} else if(s[1] == 'M'){
    			LL x, y;
    			scanf("%lld%lld", &x, &y);
    			printf("%lld
    ", getmin(x, y));
    		} else {
    			LL x, y;
    			scanf("%lld%lld", &x, &y);
    			invert(x, y);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    bzoj 1030 [JSOI2007]文本生成器
    Swift 学习笔记 (闭包)
    Swift 学习笔记 (函数)
    HTML 学习笔记 JQueryUI(Interactions,Widgets)
    HTML 学习笔记 JQuery(表单,表格 操作)
    HTML 学习笔记 JQuery(animation)
    HTML 学习笔记 JQuery(盒子操作)
    HTML 学习笔记 JQuery(事件)
    HTML 学习笔记 JQuery(DOM 操作3)
    HTML 学习笔记 JQuery(DOM 操作2)
  • 原文地址:https://www.cnblogs.com/darklove/p/6874869.html
Copyright © 2011-2022 走看看