BSOJ 4490 避难向导
题目大意:树上的每一个节点都有一个d[i],定义为离最远节点的距离,还有一个s[i]=(d[i]+a)×b%c,再m次询问,每次询问给定(x,y,q),要求求出(x,y)路径上距x最近的一个点,且满足当前点的s[i]≥q。 emm...这一看就是两道题强行拼起来的,先求出s[i],然后在处理路径上的询问。 显然对于任意点,距离它最远的点一定是直径的两个端点之一,可以用两次DFS把直径的两端求出来,再把两个距离取个max就行了,算完d[i]后就可以算出s[i]啦。 一看到路径上的询问,我就想起了树剖,但冷静后再想想,这是一道静态问题!直接树上倍增乱搞就行了。 我的思路是这样的: p[i][j]表示i的第2 k 个祖先,g[i][j]表示i到它的第2 k 个祖先中s[i]的最大值(不包含i本身) 对于任意一条路径,都可以从LCA(x,y)中拆开(如图) 分为两段(x,LCA(x,y)),(LCA(x,y),y)讨论 在(x,LCA(x,y))上时,设Ask(x,k,q)为x到2 k 祖先中第一个s[i]≥q的i(不含x),通过二分的思想: Ask(x,k,q)=-1 (g[i][k]<q) Ask(x,k,q)=p[x][0] (g[i][0]≥q && k=0) Ask(x,k,q)=Ask(x,k-1,q) Ask(x,k,q)=Ask(p[x][k-1],k-1,q) (Ask