社区讨论

求debug

P2590[ZJOI2008] 树的统计参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lrsm20lt
此快照首次捕获于
2024/01/25 10:44
2 年前
此快照最后确认于
2024/01/25 12:43
2 年前
查看原帖
代码在最后输出时有问题,求改正
CPP
#include<bits/stdc++.h>
using namespace std;
int n,a,b;
int wver[30010],whead[30010],wnext[30010];
int tot,wtime;//时间戳
int fa[30010];//父节点
int dep[30010];//深度
int wsize[30010];//节点个数
int son[30010];//重儿子
int top[30010];//当前重链的顶点
int seg[30010];//当前点在线段树中的点
int rev[30010];//线段树中的点在实际中的点
struct TREE//线段树
{
	int l,r,dat;
}tree1[60020];
TREE tree2[60020];
int w[30010];
void add(int x,int y)
{
	wver[tot++]=y;//子节点
	wnext[x]=whead[x];//下一个子节点
	whead[x]=tot;//最后一个输入的子节点
}
void dfs1(int x,int pa)
{
	wsize[x]=1;
	fa[x]=pa;
	dep[x]=dep[pa]+1;
	for(int i=whead[x];i;i=wnext[i])
	{
		int y=wver[i];
		if(y!=pa)
		{
			dfs1(y,x);
			wsize[x]+=wsize[y];//累加自身节点个数
			if(wsize[y]>wsize[son[x]])
			{
				wsize[son[x]]=wsize[y];
			}
		}
	}
	return;
}
void dfs2(int x)
{
	if(son[x])//走重儿子
	{
		seg[son[x]]=++wtime;//线段树标记
		top[son[x]]=top[x];//顶点标记
		rev[wtime]=son[x];//映射标记
		dfs2(son[x]);
	}
	for(int i=whead[x];i;i=wnext[i])
	{
		int y=wver[i];
		if(!son[y])
		{
			seg[y]=++wtime;//线段树标记
			top[y]=y;//顶点自我标记
			rev[wtime]=y;//映射标记
			dfs2(y);
		}
	}
	return;
}
void set1(int p,int l,int r)//建线段树(sum)
{
	tree1[p].l=l;
	tree1[p].r=r;
	if(l==r)
	{
		tree1[p].dat=w[l];
		return;
	}
	int mid=(l+r)/2;
	set1(p*2,l,mid);
	set1(p*2+1,mid+1,r);
	tree1[p].dat=tree1[p*2].dat+tree1[p*2+1].dat;
	return;
}
void set2(int p,int l,int r)//建线段树(max)
{
	tree1[p].l=l;
	tree1[p].r=r;
	if(l==r)
	{
		tree1[p].dat=w[l];
		return;
	}
	int mid=(l+r)/2;
	set2(p*2,l,mid);
	set2(p*2+1,mid+1,r);
	tree2[p].dat=max(tree1[p*2].dat,tree1[p*2+1].dat);
	return;
}
int ask3(int p,int l,int r,int pd)//线段树查询
{
	if(pd==1)//(sum)
	{
		if(l<=tree1[p].l&&r>=tree1[p].r)
			return tree1[p].dat;
		int mid=(tree1[p].l+tree1[p].r)/2;
		int val=-(1<<30);
		if(l<=mid)
		{
			val+=ask3(p*2,l,r,pd);
		}
		if(r>mid)
		{
			val+=ask3(p*2+1,l,r,pd);
		}
		return val;
	}
	else//(max)
	{
		if(l<=tree2[p].l&&r>=tree2[p].r)
			return tree2[p].dat;
		int mid=(tree2[p].l+tree2[p].r)/2;
		int val=-(1<<30);
		if(l<=mid)
		{
			val=max(val,ask3(p*2,l,r,pd));
		}
		if(r>mid)
		{
			val=max(val,ask3(p*2+1,l,r,pd));
		}
		return val;
	}
}
int ask1(int u,int v)//求最大权值
{
	int suml=0;
	if(top[u]==top[v])
	{
		if(seg[u]>seg[v])
		{
			int g=u;
			u=v;
			v=g;
		}
		suml=max(suml,ask3(1,seg[u],seg[v],2));
	}
	else
	{
		while(top[u]!=top[v])
		{
			if(dep[u]>dep[v])
			{
				suml=max(suml,ask3(1,top[u],seg[u],2));
				u=fa[top[u]];
			}
			else
			{
				suml=max(suml,ask3(1,top[v],seg[v],2));
				v=fa[top[v]];
			}
		}
		if(seg[u]>seg[v])
		{
			int g=u;
			u=v;
			v=g;
		}
		suml=max(suml,ask3(1,seg[u],seg[v],2));
	}
	return suml;
}
int ask2(int u,int v)//求路径权值和
{
	int suml=0;
	while(top[u]!=top[v])
	{
		if(dep[u]>dep[v])
		{
			suml+=ask3(1,top[u],seg[u],1);
			u=fa[top[u]];
		}
		else
		{
			suml+=ask3(1,top[v],seg[v],1);
			v=fa[top[v]];
		}
	}
	if(seg[u]>seg[v])
	{
		int g=u;
		u=v;
		v=g;
	}
	suml+=ask3(1,seg[u],seg[v],1);
	return suml;
}
int main()
{
	cin>>n;
	for(int i=0;i<n;++i)
	{
		cin>>a>>b;
		add(a,b);
		add(b,a);
	}
	for(int i=1;i<=n;++i)
	{
		cin>>w[i];
	}
	dfs1(1,1);
	wtime=1;
	top[1]=1;
	seg[1]=1;
	rev[1]=1;
	dfs2(1);
	set1(1,1,n);
	set2(1,1,n);
	//初始化完成
	int q;
	cin>>q;
	string s;
	int u,v;
	for(int T=0;T<q;++T)
	{
		cin>>s;
		cin>>u>>v;
		if(s[0]=='C')
		{
			w[u]=v;
		}
		else if(s=="QMAX")
		{//对应操作II
			cout<<ask1(u,v)<<endl;
			//cout<<"???";
		}
		else
		{//对应操作III
			cout<<ask2(u,v)<<endl;
			cout<<"???";//这里循环输出
		}
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...