树剖,没过样例,求助
查看原帖
树剖,没过样例,求助
361965
K2Cr2O7楼主2020/12/13 15:26

调试情况

(这题里根节点应该是没有给定的罢)

  • 以 1 为根节点,QMAX 的结果全部正确,QSUM 有问题

  • 以 2 为根节点,QMAX 和 QSUM 的结果都有问题

所以由此看来两个都有问题?

代码

#include<bits/stdc++.h> 
using namespace std;
typedef long long LL; 
const int maxn=30004;
char op[14],res[maxn*10];
int n,m,u,v,x,y,z,tot,a[maxn],w[maxn];

inline void reads(char *s){
	char c=getchar();int cnt=0;
	for(;c<'A'||c>'Z';c=getchar());
	for(;c>='A'&&c<='Z';c=getchar())
		s[cnt++]=c;
}

inline void read(int &x){
	bool f=0;char c=getchar();x=0;
	for(;c<'0'||c>'9';c=getchar());
	for(;c>='0'&&c<='9';c=getchar())
		x=x*10+(c^48);
}

void save(const LL x){
	if(x>9)
		save(x/10);
	res[++tot]=x%10+48;
}

inline void _swap(int &a,int &b){ a^=b;b=a^b;a^=b;}

inline const int _max(const int &a,const int &b){
	return a>b?a:b;
}

namespace gragh{
	
	int cnt,head[maxn],to[maxn<<1],nxt[maxn<<1];
	
	inline void add_edge(int a,int b){
		++cnt;
		nxt[cnt]=head[a];
		to[cnt]=b;
		head[a]=cnt;
	}
	
}

namespace segt{
	
	LL s[maxn<<2],maxi[maxn<<2];
	
	void assign(int l,int r,int node,int p,int v){
		if(l==r){
			s[node]=maxi[node]=v;
			return ;
		}
		int mid=(l+r)>>1,lnode=node<<1,rnode=node<<1|1;
		if(p<=mid)
			assign(l,mid,lnode,p,v);
		else
			assign(mid+1,r,rnode,p,v);
		s[node]=s[lnode]+s[rnode];
		maxi[node]=_max(maxi[lnode],maxi[rnode]);
	} 
	
	LL sum(int l,int r,int node,int start,int end){
		if(start<=l&&r<=end)
			return s[node];
		int mid=(l+r)>>1,lnode=node<<1,rnode=node<<1|1;
		LL ans=0;
		if(start<=mid)
			ans+=sum(l,mid,lnode,start,end);
		if(end>mid)
			ans+=sum(mid+1,r,rnode,start,end);
		return ans;
	}
	
	LL max(int l,int r,int node,int start,int end){
		if(start<=l&&r<=end)
			return maxi[node];
		int mid=(l+r)>>1,lnode=node<<1,rnode=node<<1|1;
		LL ans=0;
		if(start<=mid)
			ans=max(l,mid,lnode,start,end);
		if(end>mid)
			ans=_max(ans,max(mid+1,r,rnode,start,end));
		return ans;
	}
}

namespace chains{
	
	int cnt,d[maxn],f[maxn],t[maxn],treesz[maxn],hson[maxn],ord[maxn];
	
	void dfs1(int node,int fa,int dep){
		d[node]=dep;
		f[node]=fa;
		treesz[node]=1;
		int MAX=-1;
		for(int i=gragh::head[node];i;i=gragh::nxt[i]){
			int to=gragh::to[i];
			if(to!=fa){
				dfs1(to,node,dep+1);
				int ssz=treesz[to];
				treesz[node]+=ssz;
				if(MAX<ssz){
					MAX=ssz;
					hson[node]=to;
				}
			}
		}
	}
	
	void dfs2(int node,int top){
		ord[node]=++cnt;
		w[cnt]=a[node];
		t[node]=top;
		if(!hson[node])
			return ;
		dfs2(hson[node],top);
		for(int i=gragh::head[node];i;i=gragh::nxt[i]){
			int to=gragh::to[i];
			if(ord[to]==0)
				dfs2(to,to);
		}
	}
	
	inline int chain_sum(int a,int b){
		int ans=0;
		while(t[a]!=t[b]){
			if(d[t[a]]<d[t[b]])
				_swap(a,b);
			ans+=segt::sum(1,n,1,ord[t[a]],ord[a]);
			a=f[t[a]];
		}
		if(d[a]>d[b])
			_swap(a,b);
		ans+=segt::sum(1,n,1,ord[a],ord[b]);
		return ans;
	}
	
	inline LL chain_max(int a,int b){
		LL ans=-0x7fffffff;
		while(t[a]!=t[b]){
			if(d[t[a]]<d[t[b]])
				_swap(a,b);
			ans=_max(ans,segt::max(1,n,1,ord[t[a]],a));
			a=f[t[a]];
		}
		if(d[a]>d[b])
			_swap(a,b);
		ans=_max(ans,segt::max(1,n,1,ord[a],ord[b]));
		return ans;	
	}
	
}

signed main(){
	read(n);
	for(int i=1;i<n;i++){
		read(u),read(v);
		gragh::add_edge(u,v);
		gragh::add_edge(v,u);
	}
	for(int i=1;i<=n;i++)
		read(a[i]);
	chains::dfs1(1,0,1);
	chains::dfs2(1,1);
	for(int i=1;i<=n;i++)
		segt::assign(1,n,1,i,w[i]);
	read(m);
	while(m--){
		reads(op);read(x),read(y);
		if(op[0]=='C')
			segt::assign(1,n,1,chains::ord[x],y);
		else{ 
			if(op[1]='M')
				save(chains::chain_max(x,y));
			else
				save(chains::chain_sum(x,y));
			res[++tot]='\n';
		}
	}
	fwrite(res+1,1,tot,stdout);
	return 0;
}
2020/12/13 15:26
加载中...