首页 > 其他分享 >【代码仓库】【模板】树链剖分

【代码仓库】【模板】树链剖分

时间:2023-06-15 14:55:38浏览次数:37  
标签:剖分 int top 树链 rd dep id 模板 define

#include <bits/stdc++.h>

#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pre(i, a, b) for(int i = (a); i >= (b); i--)
#define Ede(i, u) for(int i = h[u]; i; i = ne[i])
#define go(i, a) for(auto i : a)
//#define int long long
#define uint unsigned int
#define LL long long
#define ULL unsigned long long
#define PII pair<int, int>
#define PIL pair<int, long long>
#define PLI pair<long long, int>
#define PLL pair<long long, long long>
#define mp make_pair
#define eb emplace_back
#define opb pop_back
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define sf scanf
#define prf printf
#define el putchar('\n')
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define mmc(arr1, arr2) memcpy(arr1, arr2, sizeof(arr2))
#define Db(x) prf("test(%s): ", x)
const int inf = 0x3f3f3f3f;

template <typename T> inline void rd(T &x){
	x = 0; bool f = true; char ch = getchar();
	while(ch < '0' || ch > '9'){ if(ch == '-') f = false; ch = getchar();}
	while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
	if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
using namespace std;

const int N = 2e5 + 10, M = N << 1;
int n, m, root, mod;
int h[N], e[M], ne[M], idx;
void add(int a, int b){
	e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}
int Num[N << 2], tag[N << 2];
int /*dfds1*/fa[N], dep[N], siz[N], wson[N],/*dfs2*/ id[N], cnt, top[N];
LL res;
//---
void pushup(int p){
	Num[p] = Num[ls(p)] + Num[rs(p)];
}
void addtag(int p, int l, int r, int t){
	Num[p] += (r - l + 1) * t;
	Num[p] %= mod;
	tag[p] += t;
}
void pushdown(int p, int l, int r){
	if(!tag[p]) return;
	int t = tag[p];
	int mid = (l + r) >> 1;
	addtag(ls(p), l, mid, t);
	addtag(rs(p), mid + 1, r, t);
	tag[p] = 0;
}
int a[N]/*real*/, at[N]/*input, a's teamp*/;
void build(int p, int l, int r){
	if(l == r){
		Num[p] = a[l] % mod;
		return;	
	}
	int mid = (l + r) >> 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
	pushup(p);
}
void modify(int p, int l, int r, int ql, int qr, int t){
	if(ql <= l && r <= qr){
		addtag(p, l, r, t);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(p, l, r);
	if(ql <= mid) modify(ls(p), l, mid, ql, qr, t);
	if(mid <  qr) modify(rs(p), mid + 1, r, ql, qr, t);
	pushup(p);
}
void query(int p, int l, int r, int ql, int qr){
	if(ql <= l && r <= qr){
		res = (res + Num[p]) % mod;
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(p, l, r);
	if(ql <= mid) query(ls(p), l, mid, ql, qr);
	if(mid <  qr) query(rs(p), mid + 1, r, ql, qr);
}
//---
void dfs1(int u, int f){ //fa, dep, siz, wson
	dep[u] = dep[f] + 1, fa[u] = f;
	siz[u] = 1;
	int maxson = 0;
	Ede(i, u){
		int v = e[i];
		if(v == f) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		if(siz[v] > maxson){
			maxson = siz[v];
			wson[u] = v;
		}
	}
}
void dfs2(int u, int tp){
	id[u] = ++cnt, a[cnt] = at[u]/*in->seg*/;
	top[u] = tp;
	if(!wson[u]) return;
	dfs2(wson[u], tp);
	Ede(i, u){
		int v = e[i];
		if(v == fa[u] || v == wson[u]) continue;
		dfs2(v, v);
	}
}
//---
void mrange(int x, int y, int t){
	while(top[x] != top[y]){
		if(dep[top[x]] > dep[top[y]]) swap(x, y);
		modify(1, 1, n, id[top[y]], id[y], t);
		y = fa[top[y]];
	}
	if(dep[x] > dep[y]) swap(x, y);
	modify(1, 1, n, id[x], id[y], t); 
}
int qrange(int x, int y){
	LL ans = 0;
	while(top[x] != top[y]){
		if(dep[top[x]] > dep[top[y]]) swap(x, y);
		res = 0, query(1, 1, n, id[top[y]], id[y]);
		ans = (ans + res) % mod;
		y = fa[top[y]];
	}
	if(dep[x] > dep[y]) swap(x, y);
	res = 0, query(1, 1, n, id[x], id[y]);
	ans = (ans + res) % mod;
	return ans;
}
void mson(int x, int t){
	modify(1, 1, n, id[x], id[x] + siz[x] - 1, t);
}
int qson(int x){
	int ans = 0;
	res = 0, query(1, 1, n, id[x], id[x] + siz[x] - 1);
	return ans = res;	
}
int main(){
	/*
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
	*/
	rd(n, m, root, mod);
	rep(i, 1, n) rd(at[i]);
	rep(i, 1, n-1){
		int x, y; rd(x, y);
		add(x, y), add(y, x);
	}
	dfs1(root, 0), dfs2(root, root);
	build(1, 1, n);
	rep(i, 1, m){
		int op; rd(op);
		int x, y, z;
		if(op == 1){
			rd(x, y, z); z %= mod;
			mrange(x, y, z);
		}else if(op == 2){
			rd(x, y);
			prf("%d\n", qrange(x, y));
		}else if(op == 3){
			rd(x, z); z %= mod;
			mson(x, z);
		}else{
			rd(x);
			prf("%d\n", qson(x));
		}
	}
	return 0;
}

标签:剖分,int,top,树链,rd,dep,id,模板,define
From: https://www.cnblogs.com/Seaniangel/p/17482856.html

相关文章

  • 云小课|RDS for MySQL参数模板一键导入导出,参数配置轻松搞定
    摘要:云数据库RDSforMySQL支持参数模板的导入和导出功能。本文分享自华为云社区《【云小课】【第56课】RDSforMySQL参数模板一键导入导出,参数配置轻松搞定》,作者:数据库的小云妹。云数据库RDSforMySQL支持参数模板的导入和导出功能。导入参数模板:导入后会生成一个新的参数模板,......
  • 云小课|RDS for MySQL参数模板一键导入导出,参数配置轻松搞定
    摘要:云数据库RDSforMySQL支持参数模板的导入和导出功能。本文分享自华为云社区《【云小课】【第56课】RDSforMySQL参数模板一键导入导出,参数配置轻松搞定》,作者:数据库的小云妹。云数据库RDSforMySQL支持参数模板的导入和导出功能。导入参数模板:导入后会生成一个新的参......
  • C++模板
    1.名词概念模板类,模板函数,特化模板(templatespecialization)2.注意事项模板必须在头文件中实现,以下情况除外:如果只在cpp内用到的模板函数,是可以在cpp中实现的,参见oceanbase/updateserver中的response_data_函数;还有特化的模板函数,也可以在cpp中实现,参见oceanbase/updateserver中的......
  • Luogu P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪
    【模板】中国剩余定理(CRT)/曹冲养猪题目描述自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。举个例子,假如有\(16\)头母猪,如果建了\(3\)个猪圈,剩下......
  • restart.sh脚本模板
    #!/bin/bashcd/data/openapitmp2=`ps-ef|grepold|awk'{print$2}'|xargskill-9`sleep10;apimps=`psgaux|grepold|grep-vgrep|awk'{print$2}'`if["$apim"==""]||[$apim-ge0];thentmp......
  • [C++/PTA] 有序数组(类模板)
    题目要求实现一个类模板,它可以接受一组数据,能对数据排序,也能输出数组的内容。每行输入的第一个数字为0,1,2或3:为0时表示输入结束;为1时表示将输入整数,为2时表示将输入有一位小数的浮点数,为3时表示输入字符。如果第一个数字非0,则接下来将输入一个正整数,表示即将输入的数据的数量......
  • WPF之浅谈数据模板(DataTemplate)
    数据模板有什么用简而言之,数据模板能让你更方便、更灵活的显示你的各类数据。只有你想不到,没有它做不到的(感觉有点夸张,实践之后,你就觉得一点不夸张......
  • C++ 模板类编译过程中出现“undefined reference to”问题
    问题描述C++在使用模板(template)类的时候,如果将类的成员函数的声明和实现分别放在.h头文件和.cpp源文件中,编译时会报错undefinedreferencexxx,找不到对应成员函数。起因.h文件中类的声明为://线程池,定义成模板类,为了代码的复用template<typenameT>classThreadPool{......
  • 模板(低精转高精, 输出高精, 高精乘, 高精加)
    structHighPrecision{ structNumber{ intnum[20000]; intlen; }tem; inlinevoidClear(Number&xxx){ xxx.len=0; memset(xxx.num,0,sizeof(xxx.num)); } inlineNumberChange(longlonga){ Clear(tem); intlen=0; while(a!=0){......
  • 矩阵乘法模板代码
    CImod=1e9+7;structmatrix{inta[maxm][maxm],n,m;};matrixmatrixMul(matrixp,matrixq){matrixres;res.n=p.n,res.m=q.m;f(i,0,res.n-1)f(j,0,res.m-1){ res.a[i][j]=0;f(k,0,p.m-1)......