萌新刚学OI,线段树蜜汁写挂,求大佬帮忙 awa
查看原帖
萌新刚学OI,线段树蜜汁写挂,求大佬帮忙 awa
298549
SIXIANG32楼主2020/12/12 22:05
#include<iostream>
#include<vector>
#define MAXN 100000
using namespace std;
int f[MAXN*4+10],S[MAXN*4+10],M[MAXN*4+10],a[MAXN+10],n;
int de[MAXN+10],son[MAXN+10],fa[MAXN+10],siz[MAXN+10];
int ind[MAXN+10],cnt=0,top[MAXN+10],who[MAXN+10];
vector<int>tree[MAXN+10];
int ls(int now){return now<<1;  }
int rs(int now){return now<<1|1;}
void push_up(int now)
{
	S[now]=S[ls(now)]+S[rs(now)];
	M[now]=max(M[ls(now)],M[rs(now)]);
}
void build(int l,int r,int now)
{
	if(l==r)
	{
		S[now]=M[now]=a[who[l]];
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(now));
	build(mid+1,r,rs(now));
	push_up(now);
}
int ask_max(int l,int r,int s,int t,int now)
{
	if(l<=s&&t<=r)return M[now];
	cout<<l<<' '<<r<<' '<<s<<' '<<t<<' '<<now<<endl;
	int mid=(s+t)>>1,maxn=-725;
	if(l<=mid)maxn=max(maxn,ask_max(l,r,s,mid ,ls(now)));
	if(r>mid)maxn=max(maxn,ask_max(l,r,mid+1,t,rs(now)));
	return maxn;
}
int ask_sum(int l,int r,int s,int t,int now)
{
	if(l<=s&&t<=r)return S[now];
	int mid=(s+t)>>1,sum=0;
	if(l<=mid)sum+=(ask_sum(l,r,s,mid ,ls(now)));
	if(r>mid)sum+=(ask_sum(l,r,mid+1,t,rs(now)));
	return sum;
}
void updata(int q,int s,int t,int now,int val)
{
	int mid=(s+t)>>1;
	if(s==t)
	{
		S[now]=M[now]=val;
		return ;
	}
	if(q<=mid)updata(q,s,mid,ls(now),val);
	else updata(q,mid+1,t,rs(now),val);
	push_up(now);
}
//线段树 
void dfs1(int u,int fat)
{
	siz[u]=1,fa[u]=fat,de[u]=de[fat]+1;
	int maxn=0;
	for(int p=0;p<tree[u].size();p++)
	{
		int v=tree[u][p];
		if(v==fat)continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>maxn)
			son[u]=v,maxn=siz[v];
	}
}
void dfs2(int u,int T)
{
	ind[u]=++cnt,who[cnt]=u,top[u]=T;
	if(!son[u])return ;
	dfs2(son[u],T);
	for(int p=0;p<tree[u].size();p++)
	{
		int v=tree[u][p];
		if(v!=fa[u])
			if(v!=son[u])
				dfs2(v,v);
	}
}
//树剖预处理
int QMAX(int u,int v)
{
	int maxn=-0x3f3f3f3f;
	while(top[u]!=top[v])
	{
		if(de[top[u]]>de[top[v]])swap(u,v);
		maxn=max(maxn,ask_max(ind[top[u]],ind[u],1,n,1));
		u=fa[top[u]];
	}
	if(de[u]>de[v])swap(u,v);
	maxn=max(maxn,ask_max(ind[u],ind[v],1,n,1));
	return maxn;
}
int QSUM(int u,int v)
{
	int sum=0;
	while(top[u]!=top[v])
	{
		if(de[top[u]]>de[top[v]])swap(u,v);
		sum+=ask_sum(ind[top[u]],ind[u],1,n,1);
		u=fa[top[u]];
	}
	if(de[u]>de[v])swap(u,v);
	sum+=ask_sum(ind[u],ind[v],1,n,1);
	return sum;
}
void CHANGE(int u,int val)
{
	updata(who[u],1,n,1,val);
}
//树剖 
void link(int x,int y)
{
	tree[x].push_back(y);
	tree[y].push_back(x);
} 
void test()
{
	for(int p=1;p<=n;p++)
		cout<<p<<" siz"<<siz[p]<<" fa"<<fa[p]<<" de"<<de[p]<<endl;
	for(int p=1;p<=n;p++)
		cout<<p<<" ind"<<ind[p]<<" "<<top[p]<<endl;
}
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin>>n;
	for(int p=1,x,y;p<n;p++)
		cin>>x>>y,link(x,y);
	for(int p=1;p<=n;p++)
		cin>>a[p];
	de[1]=1,fa[1]=1;
	dfs1(1,-1),dfs2(1,1);
	build(1,n,1);
	test();
	int q;
	cin>>q;
	string str;
	while(q--)
	{
		int x,y;
		cin>>str>>x>>y;
		if(str[1]=='H')CHANGE(x,y);
		else if(str[1]='M')cout<<QMAX(x,y)<<endl;
		else if(str[1]='S')cout<<QSUM(x,y)<<endl;
	}
}
 

目测是 ask_max 函数出错了,里面有调试的输出。l 和 r 是要找的目标区间,传参传着传着他就变成 0 0 了,然后就死循环了。

萌新很懵,求助大佬啊/kk

2020/12/12 22:05
加载中...