数据结构练习

T-Shirts

problem

\(n\) 种 T 恤,每种有价格 \(c_i\) 和品质 \(q_i\),有 \(m\) 个人要买 T 恤,第 \(i\) 个人有 \(b_i\) 元,每人每次都会买一件能买得起的 \(q_i\) 最大的 T 恤,如果有多个 \(q_i\) 最大的 T 恤,会从价格低的开始买。一个人只能买一种 T 恤一件,所有人之间都是独立的。

问最后每个人买了多少件 T 恤?

\(1\leq n,m\leq 2\times10^5\)\(1\leq c_i,q_i,b_i\leq 10^9\)

solution

平衡树维护每个人手中的钱,将T恤排序后依次考虑,修改树上的值并计算贡献。重复部分暴力插入,不重复部分打标记

Count on a tree

problem

给定 \(n\) 个结点的树,每个结点有一种颜色。\(m\) 次询问,每次询问给出 \(u\)\(v\),回答 \(u\)\(v\) 之间的路径上的结点的不同颜色数。颜色是不超过 \(2\times 10^9\) 的非负整数。
\(1\le n\le 4\times 10^4\)\(1\le m\le 10^5\)

solution

树上莫队+数颜色

强制在线?

树分块,\(\text{bitset}\) 维护路径颜色

Hello world!

problem

\(n\) 个点的树,每个节点有一个值 \(a_i\)\(Q\) 次跳跃,每次跳跃会从一个点 \(s\) 出发跳到 \(t\)。每次跳跃会有一个步频 \(k\),表示如果从当前点到 \(t\) 的简单路径长度不超过 \(k\),那么就直接跳到 \(t\),否则沿着简单路径跳过恰好 \(k\) 条边。

每次跳跃会做下面两种操作之一

  • 输出到达过的点的 \(a_i\) 之和
  • 将到达过的点的 \(a_i\) 变为 \(\lfloor\sqrt{a_i}\rfloor\)

\(n\leq 5\times 10^4\)\(Q\leq 4\times 10^5\)\(1\leq a_i\leq 10^{13}\)

solution

每个数最多开根 \(\log\)

\(k\) 较小时建出虚树,树状数组 \(+\) 并查集维护

\(k\) 较大时暴力跳

小蓝的好友

problem

有一块 \(R\times C\) 的长方形土地。里面随机分布着 \(N\) 个资源点,第 \(i\) 个资源点的坐标为 \((x_i,y_i)\) ,求至少包含一个资源点的矩形区域的数量。

\(1\le R,C\le 4\times 10^4\)\(1\le N\le 10^5\)
,保证资源点的位置两两不同,且位置随机生成

solution

扫描线 \(+\) \(\text{treap}\) 维护笛卡尔树

大森林

problem

\(n\) 棵树,编号为 \(1\)\(n\)。出始每棵树只有一个生长节点,有三种操作。

  • 生长操作:将第 \(l\) 棵树到第 \(r\) 棵树的生长节点下面长出一个子节点,子节点的标号为上一个生长操作生成的点标号加 \(1\)(特殊的,第一个生长操作产生的子节点标号为 \(2\)), \(l\)\(r\) 之间的树长出的节点标号都相同

  • 修改操作:将第 \(l\) 棵树到第 \(r\) 棵树的生长节点改到标号为 \(x\) 的节点。对于 \(i\) 这棵树,如果标号 \(x\) 的点不在其中,那么这个操作对该树不产生影响

  • 查询操作:询问第 \(x\) 棵树中节点 \(u\) 到节点 \(v\) 点的距离

\(N\leq 10^5\)\(M\leq 2\times 10^5\)

solution

发现询问可以在所有操作之后再做,将操作离线做扫描线

\(\text{LCT}\)维护一棵树

每次修改操作新建一个虚节点连接在上一个虚节点后,之后的生长操作的点连在最后一个虚节点上

扫描线进入一个修改区间时将对应的虚节点 \(\text{cut}\) 掉再 \(\text{link}\) 到修改到的节点上,离开时 \(\text{link}\) 回来

Escape Through Leaf

problem

有一颗 \(n\) 个节点的树。每个节点有两个权值,第 \(i\) 个节点的权值为 \(a_i\)\(b_i\)

你可以从一个节点跳到它的子树内除自己外的任意一个节点上。从节点 \(x\) 跳到节点 \(y\) 的花费为 \(a_x\times b_y\)。跳跃多次走过一条路径的总费用为每次跳跃的费用之和。请分别计算出每个节点到达树的每个叶子节点的费用中的最小值。

\(2\leq n\leq10^5\)\(-10^5\leq a_i,b_i\leq 10^5\)

solution

写出dp式子,\(f[i]\) 表示 \(i\) 节点的答案

\[f[i]=\min_{j\in sub_i}\{f[j]+a[i]\times b[j]\} \]

\(y=f[i]\)\(x=a[i]\)\(k=b[j]\)\(b=f[j]\) 可以将式子写为 \(y=kx+b\) 的形式,李超线段树 \(+\) \(\text{dsu on tree}\)

带插入区间K小值

problem

长为 \(n\) 的序列,单点插入、单点赋值、区间k小值查询

强制在线

\(n\leq 35000\),插入个数 \(\le 35000\),修改个数 \(\le 70000\),查询个数 \(\le 70000\)\(0 \le\) 每时每刻的权值 \(\le 70000\)

solution

块状链表+值域分块

problem

给你一个 \(n\) 个点的有根树,\(1\) 为根,带边权,有 \(m\) 次操作。

  • \(x\) 的子树中第 \(k\) 小的深度的值,如果子树中没有 \(k\) 个点则输出 \(-1\)
  • \(x\)\(x\) 父亲的边权加上 \(k\)

保证每次操作 \(2\)\(k\) 以及原树的边权小于等于一个数 \(\text{len}\)

\(n,m\leq 10^5\)\(\text{len}\leq 10\)

solution

\(\text{dfs}\) 序分块,二分答案 \(+\) 块内排序 \(+\) 块内二分可以做到 \(O(n\sqrt{n}\log^2n)\)

发现 \(\text{len}\) 只有 \(10\),于是可以维护每个块的极差,每隔一段时间将块重构,当极差大于某个设定值时将块分裂,这样就可以用桶排序 \(+\) 前缀和,也不需要块二分了,复杂度 \(O(n\sqrt{n}\log n)\)

posted @ 2023-09-20 16:31  imyhy  阅读(28)  评论(0)    收藏  举报