NOIp2012开车旅行

本文详细介绍了一种使用倍增技巧处理复杂路径查询问题的方法。通过预处理阶段利用set进行高效的节点查询,并结合线段树等数据结构优化计算过程,进而实现快速路径求和。文章深入解析了如何基于倍增思想构建查询表g[i][j]和路径和表f[i][j][0]及f[i][j][1],并给出了具体的转移方程。
思路
我觉得难的是预处理,非常的麻烦;倍增比较好理解;
首先可以用线段树啊,双向链表啊,平衡树啊,二叉搜索树啊什么的(雾),我用的是set,倒序查找(因为只能走到比当前点序号要大的点),在set中查找当前的元素,然后找左边的两个,右边的两个(要注意判断是否有该元素),然后用nextA[i].,nextB[i],记录在点i,A和B分别要走到哪一点,lenA[i],lenB[i],记录点i,j走到nextA[i],nextB[i]所走的路程;处理完之后就可以循环一遍,更新g[i][0],f[i][0][0],f[i][0][1],(g[i][j]表示从点i出发,走了2^j轮(!!!注意是轮)后到达的点,f[i][j][0],表示点i出发经过2^j轮后到达的点,小A走的路径和,f[i][j][1]表示小B走的路径和);

那么g[i][0]=next2[next[1]],f[i][0][0]=lenA[i],f[i][0][1]=lenB[next1[i]];仔细理解下;

处理完之后就可以倍增了;
转移方程:
g[i][j]=g[g[i][j-1]][j-1];
f[i][j][0]=f[i][j-1][0]+f[g[i][j-1]][j-1][0];
f[i][j][1]=f[i][j-1][1]+f[g[i][j-1]][j-1][1];

之后就是处理询问了,从log2(n)开始枚举,如果能走就走,不能走继续下一个,要注意一点,枚举完之后要判断小A是不是能够再走一步,对于第一个询问,要注意精度的问题,把除法转化为乘法;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值