• P3384 【模板】轻重链剖分


    P3384 【模板】轻重链剖分

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int readint(){
    	int x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') f = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x * f;
    }
    
    int MOD;
    const int maxn  = 2e5 + 5;
    struct Tree{
    	int sum;
    	int lazy;
    };
    
    Tree node[maxn << 2];
    int a[maxn];
    int id[maxn],pre[maxn],top[maxn];
    int dep[maxn],fa[maxn],son[maxn];
    int siz[maxn];
    vector<int> e[maxn];
    int m,n,r;
    
    void push_up(int i){
    	node[i].sum = node[i << 1].sum + node[i << 1|1].sum;
    	node[i].sum %= MOD;
    }
    
    void push_down(int i,int m){
    	node[i << 1].lazy += node[i].lazy;
    	node[i << 1].lazy %= MOD;
    	node[i << 1|1].lazy += node[i].lazy;
    	node[i << 1|1].lazy %= MOD;
    	node[i << 1].sum += node[i].lazy * (m - (m >> 1));
    	node[i << 1].sum %= MOD;
    	node[i << 1|1].sum += node[i].lazy * (m >> 1);
    	node[i << 1|1].sum %= MOD;
    	node[i].lazy = 0;
    }
    
    void build(int i,int l,int r){
    	if(l == r){
    		node[i].sum = a[id[l]];
    		return;
    	} 
    	int mid = l + r >> 1;
    	build(i << 1,l,mid);
    	build(i << 1|1,mid + 1,r); 
    	push_up(i); 
    }
    
    int res;
    
    void update(int i,int l,int r,int L,int R,int v){
    	if(l >= L && r <= R) {
    		node[i].lazy += v;
    		node[i].sum += v * (r - l + 1) % MOD;
    		node[i].sum %= MOD;
    		return;
    	}
    	if(node[i].lazy) push_down(i,r - l +1 );
    	int mid = l + r >> 1;
    	if(L <= mid) update(i << 1,l,mid,L,R,v);
    	if(R > mid) update(i << 1|1,mid + 1,r,L,R,v); 
    	push_up(i);
    }
    
    
    void query(int i,int l,int r,int L,int R){
    	if(l >= L && r <= R){
    		res += node[i].sum;
    		res %= MOD;
    		return;
    	}
    	if(node[i].lazy) push_down(i,r - l + 1);
    	int mid = l + r >> 1;
    	if(L <= mid) query(i << 1,l,mid,L,R);
    	if(R > mid) query(i << 1|1,mid + 1,r,L,R);
    }
    
    void dfs1(int u){
    	siz[u] = 1;
    	for(auto v:e[u]){
    		if(v == fa[u]) continue;
    		fa[v] = u;
    		dep[v] = dep[u] + 1;
    		dfs1(v);
    		siz[u] += siz[v];
    		if(siz[v] > siz[son[u]])
    			son[u] = v;
    	}
    }
    
    int tt;
    
    void dfs2(int u,int x){
    	pre[u] = ++tt;
    	id[tt] = u;
    	top[u] = x;
    	if(!son[u]) return;
    	dfs2(son[u],x);
    	for(auto v:e[u]){
    		if(v == fa[u] || v == son[u]) continue;
    		dfs2(v,v);
    	}
    }
    
    int qRange(int x,int y){
    	int ans = 0;
    	while(top[x] != top[y]){
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		res = 0;
    		query(1,1,n,pre[top[x]],pre[x]);
    		ans += res;
    		ans %= MOD;
    		x = fa[top[x]];
    	}
    	if(dep[x] > dep[y]) swap(x,y);
    	res = 0;
    	query(1,1,n,pre[x],pre[y]);
    	ans += res;
    	return  ans % MOD;
    }
    
    int qSon(int x){
    	res = 0;
    	query(1,1,n,pre[x],pre[x] + siz[x] - 1);
    	return res;
    }
    
    void updRange(int x,int y,int k){
    	k %= MOD;
    	while(top[x] != top[y]){
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		update(1,1,n,pre[top[x]],pre[x],k);
    		x = fa[top[x]];
    	}
    	if(dep[x] > dep[y]) swap(x,y);
    	update(1,1,n,pre[x],pre[y],k);
    }
    
    void updSon(int x,int k){
    	update(1,1,n,pre[x],pre[x] + siz[x] - 1,k);
    }
    
    int main(){
    	n = readint();
    	m = readint();
    	r = readint();
    	MOD = readint();
    	for(int i = 1;i <= n;i++)
    		a[i] =  readint();
    	for(int i = 1;i < n;i++){
    		int x = readint();
    		int y = readint();
    		e[x].push_back(y);
    		e[y].push_back(x);
    	}
    	dfs1(r);
    	dfs2(r,r);
    	build(1,1,n);
    	while(m--){
    		int k,x,y,z;
    		k = readint();
    		if(k == 1){
    			x = readint();
    			y = readint();
    			z = readint();
    			updRange(x,y,z);
    		}
    		else if(k == 2){
    			x = readint();
    			y = readint();
    			printf("%d
    ",qRange(x,y));
    		}
    		else if(k == 3){
    			x = readint();
    			y = readint();
    			updSon(x,y);
    		}
    		else {
    			x = readint();
    			printf("%d
    ",qSon(x));
    		}
    	} 
    }
    
  • 相关阅读:
    rsync
    typora 页内跳转
    shell脚本搭建redis集群
    Html
    python json模块
    Appium
    selenium+python
    jmeter+ant+jenkins接口自动化测试框架
    测试小结
    面向对向
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13916830.html
Copyright © 2020-2023  润新知