zoukankan      html  css  js  c++  java
  • BZOJ 2631 tree / Luogu P1501 [国家集训队]Tree II (LCT,多重标记)

    题意

    一棵树,有删边加边,有一条链加/乘一个数,有询问一条链的和

    分析

    LCT,像线段树一样维护两个标记(再加上翻转标记就是三个),维护size,就行了

    CODE

    #include<bits/stdc++.h>
    using namespace std;
    inline void read(int &num) {
    	char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg = -flg;
    	for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar()); num*=flg;
    }
    const int MAXN = 100005;
    const int mod = 51061;
    namespace LCT {
    	#define ls ch[x][0]
    	#define rs ch[x][1]
    	int ch[MAXN][2], fa[MAXN], w[MAXN], sz[MAXN], mul[MAXN], add[MAXN], sum[MAXN];
    	bool rev[MAXN];
    	inline bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }
    	inline bool get(int x) { return ch[fa[x]][1] == x; }
    	inline void upd(int x) {
    		sum[x] = (sum[ls] + sum[rs] + w[x]) % mod;
    		sz[x] = sz[ls] + sz[rs] + 1;
    	}
    	inline void pusha(int x, int val) {
    		if(!x) return;
    		sum[x] = (sum[x] + 1ll * val * sz[x]) % mod;
    		w[x] = (w[x] + val) % mod;
    		add[x] = (add[x] + val) % mod;
    	}
    	inline void pushm(int x, int val) {
    		if(!x) return;
    		sum[x] = 1ll * sum[x] * val % mod;
    		w[x] = 1ll * w[x] * val % mod;
    		add[x] = 1ll * add[x] * val % mod;
    		mul[x] = 1ll * mul[x] * val % mod;
    	}
    	inline void mt(int x) {
    		if(rev[x]) rev[ls]^=1, rev[rs]^=1, rev[x]^=1, swap(ls, rs);
    		if(mul[x]!=1) pushm(ls, mul[x]), pushm(rs, mul[x]), mul[x] = 1;
    		if(add[x]) pusha(ls, add[x]), pusha(rs, add[x]), add[x] = 0;
    	}
    	void mtpath(int x) { if(!isr(x)) mtpath(fa[x]); mt(x); }
    	inline void rot(int x) {
    		int y = fa[x], z = fa[y]; bool l = get(x), r = l^1;
    		if(!isr(y)) ch[z][get(y)] = x;
    		fa[ch[x][r]] = y; fa[y] = x; fa[x] = z;
    		ch[y][l] = ch[x][r]; ch[x][r] = y;
    		upd(y), upd(x);
    	}
    	inline void splay(int x) {
    		mtpath(x);
    		for(; !isr(x); rot(x))
    			if(!isr(fa[x])) rot(get(fa[x])==get(x)?fa[x]:x);
    	}
    	inline int access(int x) { int y = 0;
    		for(; x; x=fa[y=x]) splay(x), ch[x][1] = y, upd(x);
    		return y;
    	}
    	inline void bert(int x) { access(x), splay(x), rev[x]^=1; }
    	inline int sert(int x) {
    		access(x), splay(x);
    		for(; ch[x][0]; x=ch[x][0]);
    		return x;
    	}
    	inline void Link(int x, int y) { bert(x); if(sert(y) != x) fa[x] = y; }
    	inline void Cut(int x, int y) { bert(x); if(sert(y) == x && fa[x] == y && !ch[x][1]) fa[x] = ch[y][0] = 0, upd(y); }
    	inline int split(int x, int y) { bert(x), access(y), splay(y); return y; }
    	inline void Add(int x, int y, int val) { pusha(split(x, y), val); }
    	inline void Mul(int x, int y, int val) { pushm(split(x, y), val); }
    	inline int Query(int x, int y) { return sum[split(x, y)]; }
    	#undef ls
    	#undef rs
    }
    using namespace LCT;
    int n, q;
    int main() {
    	//freopen("sample.txt", "r", stdin);
    	read(n), read(q);
    	for(int i = 1; i <= n; ++i)
    		w[i] = sum[i] = mul[i] = sz[i] = 1;
    	for(int i = 1, x, y; i < n; ++i)
    		read(x), read(y), Link(x, y);
    	char ch[2];
    	int x, y, u, v;
    	while(q--) {
    		scanf("%s", ch);
    		switch(ch[0]) {
    			case '+':
    				read(u), read(v), read(x), Add(u, v, x%mod);
    			break;
    			case '-':
    				read(u), read(v), read(x), read(y), Cut(u, v), Link(x, y);
    			break;
    			case '*':
    				read(u), read(v), read(x), Mul(u, v, x%mod);
    			break;
    			case '/':
    				read(u), read(v), printf("%d
    ", Query(u, v));
    			break;
    		}
    	}
    }
    
  • 相关阅读:
    JS 实现页面跳转
    JavaScript 获取指定的cookie值
    Jquery为单选框checkbox绑定单击事件
    “25岁博导”是“破五唯”的 正面榜样 还是 反面教材 ???
    国产软件如何让人再次失望——!20824 mindspore1.3.0gpu version can not compile from source code, because openmpi source code has bug
    sqlserver触发器引起的死锁问题
    Oracle客户端tnsnames.ora连接配置
    win7 调整C盘大小,不使用PQ
    C# 适合vs 2008和vs 2010的变量高亮highlight工具
    C# Response.Redirect引起的错误
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039381.html
Copyright © 2011-2022 走看看