重链剖分

码量浅压170行,线段树码量大

#include<bits/stdc++.h>
#define endl '\n'
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
constexpr int maxn=1e6+10;
int n,m;
int root,p;
int a[maxn];
int fa[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn];
int dfn[maxn],rnk[maxn],cnt;
struct _
{
	int l,r,sum,lazy;
}tree[maxn<<2];
int h[maxn],to[maxn],nxt[maxn],tot;
void add(int x,int y)
{
	tot++;
	to[tot]=y;
	nxt[tot]=h[x];
	h[x]=tot;
}
void pushup(int rt) {tree[rt].sum=(tree[lson].sum+tree[rson].sum)%p;}
void pushdown(int rt)
{
	if (tree[rt].lazy)
	{
		int lz=tree[rt].lazy;
		tree[rt].lazy=0;
		tree[lson].lazy=(tree[lson].lazy+lz)%p;
		tree[rson].lazy=(tree[rson].lazy+lz)%p;
		tree[lson].sum=(tree[lson].sum+lz*(tree[lson].r-tree[lson].l+1)%p)%p;
		tree[rson].sum=(tree[rson].sum+lz*(tree[rson].r-tree[rson].l+1)%p)%p;
	}
}
void build(int rt,int l,int r)
{
	tree[rt].l=l;
	tree[rt].r=r;
	if (l == r)
	{
		tree[rt].sum=a[rnk[l]]%p;
		return;
	}
	int mid=(l+r) >> 1;
	build(lson,l,mid);build(rson,mid+1,r);
	pushup(rt);
}
void update(int rt,int l,int r,int val)
{
	if (l<=tree[rt].l && tree[rt].r<=r)
	{
		tree[rt].lazy=(tree[rt].lazy+val)%p;
		tree[rt].sum=(tree[rt].sum+val*(tree[rt].r-tree[rt].l+1)%p)%p;
		return;
	}
	pushdown(rt);
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (l<=mid) update(lson,l,r,val);
	if (r>mid) update(rson,l,r,val);
	pushup(rt);
}
int query(int rt,int l,int r)
{
	int res=0;
	if (l<=tree[rt].l && tree[rt].r<=r) return tree[rt].sum%p;
	pushdown(rt);
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (l<=mid) res=(res+query(lson,l,r))%p;
	if (r>mid) res=(res+query(rson,l,r))%p;
	return res;
}
void dfs1(int x)
{
	son[x]=-1;siz[x]=1;
	for (int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if (dep[y]) continue;
		dep[y]=dep[x]+1;
		fa[y]=x;
		dfs1(y);
		siz[x]+=siz[y];
		if (son[x] == -1 || siz[y]>siz[son[x]]) son[x]=y;
	}
}
void dfs2(int x,int t)
{
	top[x]=t;
	cnt++;
	dfn[x]=cnt;rnk[cnt]=x;
	if (son[x] == -1) return;
	dfs2(son[x],t);
	for (int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if (y == son[x] || y == fa[x]) continue;
		dfs2(y,y);
	}
}
void add1(int x,int y,int val)
{
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,dfn[top[x]],dfn[x],val);
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	update(1,dfn[x],dfn[y],val);
}
int query1(int x,int y)
{
	int res=0;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		res=(res+query(1,dfn[top[x]],dfn[x]))%p;
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	res=(res+query(1,dfn[x],dfn[y]))%p;
	return res;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n >> m >> root >> p;
	for (int i=1;i<=n;i++) cin >> a[i];
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin >> x >> y;
		add(x,y);add(y,x);
	}
	dep[root]=1;
	dfs1(root);dfs2(root,root);
	build(1,1,cnt);
	while (m--)
	{
		int op;
		cin >> op;
		if (op == 1)
		{
			int x,y,z;
			cin >> x >> y >> z;
			add1(x,y,z);
		}
		else if (op == 2)
		{
			int x,y;
			cin >> x >> y;
			cout << query1(x,y) << endl;
		}
		else if (op == 3)
		{
			int x,z;
			cin >> x >> z;
			update(1,dfn[x],dfn[x]+siz[x]-1,z);
		}
		else
		{
			int x;
			cin >> x;
			cout << query(1,dfn[x],dfn[x]+siz[x]-1) << endl;
		}
	}
	return 0;
}

非mod版

int n,m,a[maxn];
struct _ {int l,r,lazy,sum;}tree[maxn<<2];
int h[maxn],to[maxn],nxt[maxn],tot;
int fa[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn];
int dfn[maxn],rnk[maxn],cnt;
void add(int x,int y) {tot++;to[tot]=y;nxt[tot]=h[x];h[x]=tot;}
void pushup(int rt) {tree[rt].sum=tree[lson].sum+tree[rson].sum;}
void pushdown(int rt)
{
	if (tree[rt].lazy)
	{
		int lz=tree[rt].lazy;
		tree[rt].lazy=0;
		tree[lson].lazy+=lz;
		tree[rson].lazy+=lz;
		tree[lson].sum+=lz*(tree[lson].r-tree[lson].l+1);
		tree[rson].sum+=lz*(tree[rson].r-tree[rson].l+1);
	}
}
void build(int rt,int l,int r)
{
	tree[rt].l=l;tree[rt].r=r;
	if (l == r) {tree[rt].sum=a[rnk[l]];return;}
	int mid=(l+r) >> 1;
	build(lson,l,mid);build(rson,mid+1,r);
	pushup(rt);
}
void update(int rt,int l,int r,int val)
{
	if (l<=tree[rt].l && tree[rt].r<=r)
	{
		tree[rt].lazy+=val;
		tree[rt].sum+=val*(tree[rt].r-tree[rt].l+1);
		return;
	}
	pushdown(rt);
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (l<=mid) update(lson,l,r,val);
	if (r>mid) update(rson,l,r,val);
	pushup(rt);
}
int query(int rt,int l,int r)
{
	int res=0;
	if (l<=tree[rt].l && tree[rt].r<=r) return tree[rt].sum;
	pushdown(rt);
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (l<=mid) res+=query(lson,l,r);
	if (r>mid) res+=query(rson,l,r);
	return res;
}
void dfs1(int x)
{
	son[x]=-1;siz[x]=1;
	for (int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if (dep[y]) continue;
		dep[y]=dep[x]+1;
		fa[y]=x;
		dfs1(y);
		siz[x]+=siz[y];
		if (son[x] == -1 || siz[y]>siz[son[x]]) son[x]=y;
	}
}
void dfs2(int x,int t)
{
	top[x]=t;
	cnt++;
	dfn[x]=cnt;rnk[cnt]=x;
	if (son[x] == -1) return;
	dfs2(son[x],t);
	for (int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if (y == son[x] || y == fa[x]) continue;
		dfs2(y,y);
	}
}
void add1(int x,int y,int val)
{
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,dfn[top[x]],dfn[x],val);
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	update(1,dfn[x],dfn[y],val);
}
int query1(int x,int y)
{
	int res=0;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		res+=query(1,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	res+=query(1,dfn[x],dfn[y]);
	return res;
}

单修+比max

#include<bits/stdc++.h>
#define endl '\n'
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
constexpr int maxn=1e6+10;
int n,m;
int a[maxn];
int fa[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn];
int dfn[maxn],rnk[maxn],cnt;
struct _
{
	int l,r,sum,lazy,maxx=-0x3fffffff;
}tree[maxn<<2];
int h[maxn],to[maxn],nxt[maxn],tot;
void add(int x,int y) {tot++;to[tot]=y;nxt[tot]=h[x];h[x]=tot;}
void pushup(int rt)
{
	tree[rt].sum=tree[lson].sum+tree[rson].sum;
	tree[rt].maxx=max(tree[lson].maxx,tree[rson].maxx);
}
void build(int rt,int l,int r)
{
	tree[rt].l=l;tree[rt].r=r;
	if (l == r)
	{
		tree[rt].sum=tree[rt].maxx=a[rnk[l]];
		return;
	}
	int mid=(l+r) >> 1;
	build(lson,l,mid);build(rson,mid+1,r);
	pushup(rt);
}
void update(int rt,int pos,int val)
{
	if (tree[rt].l == tree[rt].r)
	{
		tree[rt].sum=tree[rt].maxx=val;
		return;
	}
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (pos<=mid) update(lson,pos,val);
	else update(rson,pos,val);
	pushup(rt);
}
int query(int rt,int l,int r)
{
	int res=0;
	if (l<=tree[rt].l && tree[rt].r<=r) return tree[rt].sum;
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (l<=mid) res+=query(lson,l,r);
	if (r>mid) res+=query(rson,l,r);
	return res;
}
int query_maxx(int rt,int l,int r)
{
	int res=-0x3fffffff;
	if (l<=tree[rt].l && tree[rt].r<=r) return tree[rt].maxx;
	int mid=(tree[rt].l+tree[rt].r) >> 1;
	if (l<=mid) res=max(res,query_maxx(lson,l,r));
	if (r>mid) res=max(res,query_maxx(rson,l,r));
	return res;
}
void dfs1(int x)
{
	son[x]=-1;siz[x]=1;
	for (int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if (dep[y]) continue;
		dep[y]=dep[x]+1;
		fa[y]=x;
		dfs1(y);
		siz[x]+=siz[y];
		if (son[x] == -1 || siz[y]>siz[son[x]]) son[x]=y;
	}
}
void dfs2(int x,int t)
{
	top[x]=t;
	cnt++;
	dfn[x]=cnt;rnk[cnt]=x;
	if (son[x] == -1) return;
	dfs2(son[x],t);
	for (int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if (y == son[x] || y == fa[x]) continue;
		dfs2(y,y);
	}
}
int query1(int x,int y)
{
	int res=0;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		res+=query(1,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	res+=query(1,dfn[x],dfn[y]);
	return res;
}
int query2(int x,int y)
{
	int res=-0x3fffffff;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		res=max(res,query_maxx(1,dfn[top[x]],dfn[x]));
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	res=max(res,query_maxx(1,dfn[x],dfn[y]));
	return res;
}
int main()
{
//	freopen("1.in","r",stdin);
//	freopen("78.out","w",stdout);
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin >> x >> y;
		add(x,y);add(y,x);
	}
	for (int i=1;i<=n;i++) cin >> a[i];
	cin >> m;
	dep[1]=1;
	dfs1(1);dfs2(1,1);
	build(1,1,cnt);
	while (m--)
	{
		string op;
		cin >> op;
		if (op == "CHANGE")
		{
			int x,y;
			cin >> x >> y;
			update(1,dfn[x],y);
		}
		else if (op == "QSUM")
		{
			int x,y;
			cin >> x >> y;
			cout << query1(x,y) << endl;
		}
		else
		{
			int x,y;
			cin >> x >> y;
			cout << query2(x,y) << endl;
		}
	}
	return 0;
}
posted @ 2026-05-31 18:13  msjing  阅读(5)  评论(0)    收藏  举报