from types import GeneratorType from collections import defaultdict def bootstrap(f, stack=[]): def wrappedfunc(*args, **kwargs): if stack: return f(*args, **kwargs) else: to = f(*args, **kwargs) while True: if type(to) is GeneratorType: stack.append(to) to = next(to) else: stack.pop() if not stack: break to = stack[-1].send(to) return to return wrappedfunc n,l,r=map(int,input().split()) col="#"+input() g=[[] for _ in range(n+1)] d=[[] for _ in range(n+1)] res=[0]*(n+1) for _ in range(n-1): u,v=map(int,input().split()) g[u]+=[v] g[v]+=[u] @bootstrap def dfs(u,fa,top): ntop=u if col[u]=="R" else top d[ntop].append(u) for v in g[u]: if v==fa: continue yield dfs(v,u,ntop) yield None dfs(1,-1,0) mx=r if r>abs(l) else l for i in d[0]: res[i]=mx def check(mid,t): k=(mid+r-1)//r return k<t and (t-k)*abs(l)>=mid for x in range(1,n+1): t=len(d[x]) if t<2: continue ll=0 rr=int(1e20) while ll+1!=rr: mid=(ll+rr)//2 if check(mid,t): ll=mid else: rr=mid tot=ll while d[x]: if tot>r: tot-=r res[d[x].pop()]=r else: res[d[x].pop()]=tot break tot=ll while d[x]: if tot>abs(l): tot-=abs(l) res[d[x].pop()]=l else: res[d[x].pop()]=-tot break print(*res[1:])
dfs一次,把树划分成若干个连通块,每个块顶部都是一个红色节点(根节点除外,根节点无论是否是红色都是一个块的开始)
先特判一下根,如果根是红色,那么就和其他块一样做,如果根不是红色,那么l和r哪个绝对值大就填哪个,根这个块内的所有节点都填这个数
对于每一个块,只有一个属性,那么就是块的大小,每一个块我们一定是填入若干的正数,若干的负数,然后这些数相加等于0
只看正数,填入的正数越大,成功构造的可能就越小,一个正数都不填的时候最好构造,全部填0就可以了
二分填入的正数之和,check一下是否可行
算出要填出这么多正数至少需要多少个点,然后假设把剩下的所有点都填成负的最多的数
看看负数和的绝对值能不能大于等于正数和,如果可以,那就是一种合法的数值
感觉这题还可以加强,把指定根为1去掉,任选一个点作为起点,换根可做