树链剖分0分求调
查看原帖
树链剖分0分求调
1151401
xyin楼主2024/6/6 17:22
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn=1e5+10;
const int INF=1e9;
int read()
{
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
int n,he[maxn],to[maxn<<1],ne[maxn<<1],tot,w[maxn<<1][2];//1为真实边的编号,0为边权 
void addedge(int u,int v,int z,int t)
{
	ne[++tot]=he[u];
	he[u]=tot;
	to[tot]=v;
	w[tot][0]=z;
	w[tot][1]=t;
}
int a[maxn],d[maxn],son[maxn],siz[maxn],fa[maxn],is[maxn];//is表示边赋给的点
void dfs1(int x) 
{
	siz[x]=1;
	for (int i=he[x];i;i=ne[i])
	{
		if (d[to[i]]) continue;
		d[to[i]]=d[x]+1;
		fa[to[i]]=x;
		is[w[i][1]]=to[i];
		a[to[i]]=w[i][0];
		dfs1(to[i]);
		siz[x]+=siz[to[i]];
		if (siz[to[i]]>siz[son[x]]) son[x]=to[i];
	}
 } 
int dfn[maxn],rnk[maxn],top[maxn],tmp;
void dfs2(int x,int t)
{
	dfn[x]=++tmp;
	rnk[tmp]=x;
	top[x]=t;
	if (!son[x]) return;
	dfs2(son[x],t);
	for (int i=he[x];i;i=ne[i])
	{
		if (to[i]==son[x]||to[i]==fa[x]) continue;
		dfs2(to[i],to[i]);
	}
}
struct node{
	int o,lz1,lz2,l,r;
}tree[maxn<<2];
void pushup(int rt)
{
	tree[rt].o=max(tree[lson].o,tree[rson].o);
}
void pushdown1(int rt)//u到v改变为w个 
{
	if (tree[rt].lz1==-1) return;
	tree[lson].lz2=tree[rt].lz2=0;
	int t=tree[rt].lz1;
	tree[rt].lz1=-1;
	tree[lson].lz1=tree[rson].lz1=t; 
	tree[lson].o=tree[rson].o=t;
}
void pushdown2(int rt)//u到v增加w个
{
	if (!tree[rt].lz2) return;
	int t=tree[rt].lz2;
	tree[rt].lz2=0;
	tree[lson].lz2+=t;tree[rson].lz2+=t;
	tree[lson].o+=t;tree[rson].o+=t;
 } 
void build(int rt,int l,int r)
{
	tree[rt].l=l;tree[rt].r=r;
	tree[rt].lz1=-1;
	if (l==r)
	{
		tree[rt].o=a[rnk[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(rt);
}
void change(int rt,int pos,int val)
{
	if (tree[rt].l==tree[rt].r)
	{
		tree[rt].o=val;
		return;
	}
	pushdown1(rt);pushdown2(rt);
	int mid=(tree[rt].l+tree[rt].r)>>1;
	if (pos<=mid) change(lson,pos,val);
	else change(rson,pos,val);
	pushup(rt);
}
void cover(int rt,int l,int r,int val)
{
	if (l<=tree[rt].l&&tree[rt].r<=r)
	{
		tree[rt].lz1=val;
		tree[rt].o=val;
		return;
	}
	pushdown1(rt);pushdown2(rt);
	int mid=(tree[rt].l+tree[rt].r)>>1;
	if (l<=mid) cover(lson,l,r,val);
	if (r>mid) cover(rson,l,r,val);
	pushup(rt);
}
void _cover(int x,int y,int w)
{
	while (top[x]!=top[y])
	{
		if (d[top[x]]>d[top[y]]) swap(x,y);
		cover(1,dfn[top[y]],dfn[y],w);
		y=fa[top[y]];
	}
	if (x==y) return;
	if (d[x]>d[y]) swap(x,y);
	cover(1,dfn[x]+1,dfn[y],w);
}
void add(int rt,int l,int r,int val)
{
	if (l<=tree[rt].l&&tree[rt].r<=r)
	{
		tree[rt].o+=val;
		tree[rt].lz2+=val;
		return;
	}
	pushdown1(rt);pushdown2(rt);
	int mid=(tree[rt].l+tree[rt].r)>>1;
	if (l<=mid) add(lson,l,r,val);
	if (mid<r) add(rson,l,r,val);
	pushup(rt);
}
void _add(int x,int y,int w)
{
	while (top[x]!=top[y])
	{
		if (d[top[x]]>d[top[y]]) swap(x,y);
		add(1,dfn[top[y]],dfn[y],w);
		y=fa[top[y]];
	}
	if (x==y) return;
	if (d[x]>d[y]) swap(x,y);
	add(1,dfn[x]+1,dfn[y],w);
}
int query(int rt,int l,int r)
{
	if (l<=tree[rt].l&&tree[rt].r<=r)
	  return tree[rt].o;
	pushdown1(rt);pushdown2(rt);int ans=-INF;
	int mid=(tree[rt].l+tree[rt].r)>>1;
	if (l<=mid) ans=max(ans,query(lson,l,r));
	if (mid<r) ans=max(ans,query(rson,l,r));
	return ans;
}
int _query(int x,int y)
{
	int ans=-INF;
	while (top[x]!=top[y])
	{
		if (d[top[x]]>d[top[y]]) swap(x,y);
		ans=max(ans,query(1,dfn[top[y]],dfn[y]));
		y=fa[top[y]];
	}
	if (x==y) return ans;
	if (d[x]>d[y]) swap(x,y);
	ans=max(ans,query(1,dfn[x]+1,dfn[y]));
	return ans;
}
int main()
{
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout); 
	n=read();
	for (int i=1,x,y,z;i<n;i++) 
	{
		x=read();y=read();z=read();
		addedge(x,y,z,i);
		addedge(y,x,z,i);
	}
	d[1]=1;
	dfs1(1);dfs2(1,1);build(1,1,n);
	string op;int k,w,u,v;
	while (cin>>op)
	{
		if (op=="Stop") break;
		else if (op=="Change")
		{
			k=read();w=read();
			change(1,dfn[is[k]],w);
		}
		else if (op=="Cover")
		{
			u=read();v=read();w=read();
			_cover(u,v,w);
		}
		else if (op=="Add")
		{
			u=read();v=read();w=read();
			_add(u,v,w);
		}
		else if (op=="Max")
		{
			u=read();v=read();
			printf("%d\n",_query(u,v));
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
4
1 2 8
1 3 7
3 4 9
Max 2 4 
Cover 2 4 5
Add 1 4 10
Change 1 16
Max 2 4 
Stop
*/
2024/6/6 17:22
加载中...