CF1806E Tree Master
2023-07-19 10:59:11
思路来源于题解:https://www.luogu.com.cn/problem/solution/CF1806E
算法:根号分治+记忆化搜索。
因为每一个查询都是同层的,我们可以只记忆层数少的(小于
然后上查过程中经过的层数多的只有
复杂度
int n,q,fa[100005],deep[100005],siz[100005],idc[100005];//idc=层id siz=层大小,s=题给f(i,i),f=记忆化数组 ll a[100005],f[100005][318],s[100005]; ll dfs(int x,int y){ if(x==y)return s[x]; if(siz[deep[x]]<=318){ if(f[x][idc[y]])return f[x][idc[y]]; return f[x][idc[y]]=f[y][idc[x]]=dfs(fa[x],fa[y])+a[x]*a[y]; } return dfs(fa[x],fa[y])+a[x]*a[y];//优雅的暴力 } int main(){ n=read(),q=read(); for(int i=1;i<=n;i++){ a[i]=read(); } for(int i=1;i<=n;i++){ if(i^1)fa[i]=read();// 因为题给 fa[i]<i,所以可以直接循环不用考虑之前没有更新过 s[i]=s[fa[i]]+a[i]*a[i]; deep[i]=deep[fa[i]]+1; idc[i]=++siz[deep[i]];//一边更新深度一边更新标号 } while(q--){ int x=read(),y=read(); printf("%lld\n",dfs(x,y)); } }
本文作者:NBest
本文链接:https://www.cnblogs.com/NBest/p/17686861.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步