12
返回列表 发新帖
楼主: bigboss789
跳转到指定楼层
上一主题 下一主题
收起左侧

[高频题] 权重随机取值题followup 权重可变 算法题求解

🔗
wisdompeak2 2021-3-30 02:12:11 | 只看该作者
全局:
bigboss789 发表于 2021-3-29 21:12
"非叶子节点存放的是对应区间的权重和"

比如我那个例子,那么root节点的val就是1500. 比如query的输入 ...

我感觉你对这棵树存放的东西是什么并没有正确的理解。
root节点的val存放的就是全部的权重和。其他节点的val存放的是对应区间的权重和。
query的输入的参数是一段区间,比如说query[0,5],表示从线段树里读取前5个球的权重和。
二分搜索的是输入的参数,试图找到一个前缀和恰好大于生成的随机数。比如说如果[0,6]恰好大于生成的随机数,那么说明这个随机数对应的是第6号球。
回复

使用道具 举报

🔗
acp_ 2021-3-30 03:59:53 | 只看该作者
全局:
本帖最后由 acp_ 于 2021-3-29 12:01 编辑

楼上两位老哥貌似说的是对的,binary search + segment tree / binary index tree. 楼主貌似纠结在了presume上了,他们的实现方式里是不需要构建presume数组的, 比如说segment tree本身就可以拿到任意区间,这样结合binary search(这个binary search不是在presume上找,不是用c++的lower_bond或者python的bisect_left,而是自己另写一段binary search),总体时间O(logn*logn),就可以找到目标位置了。

评分

参与人数 2大米 +5 收起 理由
bigboss789 + 2 给你点个赞!
不知道小帅 + 3 给你点个赞!

查看全部评分

回复

使用道具 举报

🔗
 楼主| bigboss789 2021-3-30 04:14:27 | 只看该作者
全局:
本帖最后由 bigboss789 于 2021-3-30 04:15 编辑
wisdompeak2 发表于 2021-3-30 02:12
我感觉你对这棵树存放的东西是什么并没有正确的理解。
root节点的val存放的就是全部的权重和。其他节点 ...

恩,同意。 我是搜索的方式想歪了,根据你的提示我大概写了下搜索的代码:

输入的root就是segment tree的根。 random就是随机生成的数,返回找到的id。
query(start, end) 就是query segment tree。
  1. int getId(root, int random)
  2. {
  3. int left = root.start;
  4. int right = root.end;
  5. int mid = 0;
  6. while(left < right)
  7. {
  8.   mid = left + (right - left) /2
  9.   int preSum = query(left, mid);
  10.   if preSum == random
  11.    return mid;
  12.   if preSum > random
  13.    right = id-1;
  14.   else
  15.    left = id;
  16.    random -= presum;
  17. }
  18. return left;
  19. }
复制代码

最后的TC= logN * logN。

大概就是这个思路吧?
回复

使用道具 举报

🔗
wisdompeak2 2021-3-30 04:37:24 | 只看该作者
全局:
没怎么细想,但感觉不太对劲。我改了一下。

  1. int getId(root, int random)
  2. {
  3.  int left = root.start;
  4.  int right = root.end;
  5.  int mid = 0;
  6.  while(left < right)
  7.  {
  8.   mid = left + (right - left) /2
  9.   int preSum = query(0, mid);
  10.   if preSum >= random
  11.    right = mid;
  12.   else
  13.    left = mid+1;
  14.  }
  15.  return left;
  16. }
复制代码

评分

参与人数 1大米 +2 收起 理由
bigboss789 + 2 给你点个赞!

查看全部评分

回复

使用道具 举报

🔗
 楼主| bigboss789 2021-3-30 05:22:25 | 只看该作者
全局:
wisdompeak2 发表于 2021-3-30 04:37
没怎么细想,但感觉不太对劲。我改了一下。

[mw_shl_code=java,true]int getId(root, int random)

多谢, 学习了。

你的写法应该是比较常见的。不过我觉得我的也是对的,哈哈
回复

使用道具 举报

全局:
magicsets 发表于 2021-3-29 13:53
这个问题在Weighted random sampling with a reservoir中提出了一个非常巧妙的方法,不过文章不是open acce ...

如果max weight 是bounded的话,是有on average O(1) 的方法的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表