Logo zrl123456 的博客

博客

标签
暂无

[ABC364E] Maximum Glutton 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-03 11:55:20

[ABC364E] Maximum Glutton

题目考察:dp,背包。
题目简述:
有 $n$ 个物品,拥有第 $i$ 个物品需要花费 $a_i$ 的 A 代价,$b_i$ 的 B 代价。在满足 A 代价不超过 $x$,B 代价不超过 $y$ 的基础上,他会继续选择下一个物品。直到 A 代价大于 $x$ 或 B 代价大于 $y$。求最多拥有多少件物品。
数据范围:

  • $1\le n\le 80$
  • $1\le x,y\le 10^4$
  • $\forall i\in[1,n],1\le a_i,b_i\le 10^4$

首先我们设在 A 代价不超过 $x$,B 代价不超过 $y$ 的情况下最多选 $tmp$ 个物品,则最终可以选择 $\min(n,tmp+1)$ 个物品。

暴力 dp 的话,设状态 $f_{i,j,k}$ 为选择到第 $i$ 个物品,花费了 $j$ 的 A 代价和 $k$ 的 B 代价所能选择的最大物品数量,则转移方程为:
$$f_{i,j,k}=\max(f_{i-1,j,k},f_{i-1,j-a_i,k-b_i}+1)$$ 但时间复杂度为 $\Theta(nxy)$,这样即使压去第一维也无法通过。

我们注意到他最多选 $n$ 个物品,价值非常小。那么设 $f_{i,j,k}$ 为选到第 $i$ 个物品,A 代价花费了 $j$,选出了 $k$ 个物品所花费的最小 B 代价,那么这样得到状态转移方程:
$$f_{i,j,k}=\min(f_{i-1,j,k},f_{i-1,j-a_i,k-1}+b_i)$$ 最后的时候我们压去第一维,这样时间复杂度为 $\Theta(n^2x)$,空间复杂度为 $\Theta(nx)$,可以通过。

代码

[ABC365F] Takahashi on Grid 题解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-08 13:34:21

[ABC365F] Takahashi on Grid

题目考察:ST 表,倍增。
题目简述:
有一个地图 $a$,横坐标在 $[1,n]$。地图上有一些点可以通过,对于 $i\in[1,n]$,$a_{i,l_i},a_{i,l_{i+1}},\dots,a_{i,t_i}$ 是可以通过的。然后有 $q$ 次询问,每次询问给出 $s_x,s_y,t_x,t_y$,求从 $(s_x,s_y)$ 到 $(t_x,t_y)$ 所走的最短路径。
数据范围:

  • $1\le n,q\le 2\times 10^5$
  • $\forall i\in[1,n],1\le l_i,u_i\le 10^9$
  • $\forall i\in[1,n-1],[l_i,u_i]\cup[l_{i+1},u_{i+1}]\ne\emptyset$
  • $1\le s_x,t_x\le n,l_{s_x}\le s_y\le u_{s_x},l_{t_x}\le t_y\le u_{t_x}$

我们将 $x$ 坐标为 $i$ 的所有点称为第 $i$ 层,由于每一层的可通过点都是一个区间。所以说我们用一种贪心策略(能下一层就不继续走),设我们在走到下一层要向左走:

  • 若我们的走到下下层要向左走,那么我们一直往左或下走就可以得到最短路。
  • 反之,我们肯定希望靠着右边走,这样才能更快的往下走。

那么我们可以维护一个 ST 表,$mx_{i,j}$ 表示 $\displaystyle\max_{k=i}^{i+2^j-1}(l_k)$,$mn_{i,j}$ 表示 $\displaystyle\min_{k=i}^{i+2^j-1}(u_k)$,然后我们倍增对于每一个询问一直往下跳,直到跳不下去了为止。我们在预处理出 $fl_{i,j}$ 和 $fu_{i,j}$,代表从 $l_i$ 和 $u_i$ 跳下去 $2^j-1$ 层所花费的代价,然后我们往下跳 $2^j-1$ 层,花费 $fl_{i,j}$ 或 $fu_{i,j}$($j$ 是最大的 $j$ 使 $2^j\le len$,这里的 $len$ 指还需要往下跳的层数),继续往下递归(当然我们可以用同样的方法求出 $fl$ 和 $fu$)。
这样我们每次求都是 $\Theta(\log n)$ 的,然后我们求 ST 表都是 $\Theta(n\log n)$ 的,所以总体复杂度是 $\Theta(n\log^2 n+q\log n)$。

代码

[ABC365G] AtCoder Office 题解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-08 14:49:46

[ABC365G] AtCoder Office

题目考察:根号分治,前缀和。
题目简述:
有 $n$ 个人,$m$ 次操作,第 $i$ 次操作发生第 $t_i$ 秒,若第 $p_i$ 个人在办公室里,则他出去;否则他进去。然后有 $q$ 次询问,第 $i$ 次询问给出 $x_i,y_i$,输出有多长时间第 $x_i$ 和第 $y_i$ 个人都在办公室里。
数据范围:

  • $1\le n,m,q\le 2\times 10^5$
  • $\forall i\in[1,n],1\le t_i\le 10^9,1\le p_i\le n$
  • $\forall i\in[2,n],t_{i-1}<t_i$
  • $\displaystyle\forall i\in[1,n],2|\sum_{j=1}^m[p_j=i]$
  • $1\le a_i,b_i\le n$

考虑根号分治。

对于出现次数大于等于 $B$ 的人,我们进行预处理,我们将时间节点拿出来一个一个进行处理。如果这个人在房间里,那么我们给前缀和加上前一个点到现在所过的时间。然后对于剩下的人前缀和求和即可。
对于每次询问,若两个人的进入次数都不比 $B$ 大,直接暴力两个指针统计即可。
这样时间复杂度为 $\Theta(\frac{m^2+nm}{B}+qB)$,$B$ 取 $\sqrt m$ 时时间复杂度为 $\Theta((n+m+q)\sqrt m)$。

代码

[ABC366E] Manhattan Multifocal Ellipse 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-13 19:51:37

[ABC366E] Manhattan Multifocal Ellipse

题目考察:排序,二分,前缀和。(但需要一定的思维)
题目简述: 给你 $n$ 个点,第 $i$ 个点的坐标是 $(x_i,y_i)$,求有多少个点 $(a,b)$ 使得 $(\sum_{i=1}^n|x_i-a|+|y_i-b|)\le d$。
数据范围:

  • $1\le n\le 2\times 10^5$
  • $0\le d\le 10^6$
  • $\forall i\in[1,n],-10^6\le x_i,y_i\le 10^6$

由于 X 坐标和 Y 坐标互不相干,所以我们分开讨论。

我们将 X 坐标和 Y 坐标分别排序。由于 $|x_i-a|+|y_i-b|\le d$ 的点 $(a,b)$ 才有贡献($i\in[1,n]$),那么 $|x_i-a|\le d$ 且 $|y_i-b|\le d$ 的点才有可能做出贡献。
我们枚举 X 坐标,设 $num_i$ 为当 X 坐标为 $i-2\times 10^6$ 时 X 坐标与其他点的 X 坐标的距离,$sumx_i$ 就等于 $\displaystyle\sum_{j=1}^ix_i$,那么 $num_p$ 等于(下面的 $id$ 指在序列中满足 $x_{id-1}<p-2\times 10^6$ 且 $x_{id}\ge p-2\times 10^6$ 的唯一的一个数):
$$\begin{aligned}num_p&=\sum_{i=1}^n|p-2\times 10^6-x_i|\&=|\sum_{i=1}^{id-1}p-2\times 10^6-x_i|+|\sum_{i=id}^nx_i-p+2\times 10^6|\&=|(p-2\times 10^6)(id-1)-\sum_{i=1}^{id}x_i|+|(\sum_{i=id+1}^nx_i)-(p-2\times 10^6)(n-id+1)|\&=|(p-2\times 10^6)(id-1)-sumx_i|+|sumx_n-sumx_i-(p-2\times 10^6)(n-id+1)|\end{aligned}$$ 这样我们就能求出它们之间的距离了。

然后我们设 $res_j$ 等于 $\displaystyle\sum_{i=0}^Vnum_i=j$($V$ 是值域),再对 $res$ 求前缀和。

再看 Y 坐标,跟上面一样求出 Y 坐标与其他店的 Y 坐标的总距离,设其为 $id$,若 $id\le d$,则它的贡献就是 $res_{d-id}$。

时间复杂度为 $\Theta(V\log n)$。
代码

[ABC367F] Rearrange Query 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-18 09:35:47

[ABC367F] Rearrange Query

题目考察:哈希,前缀和。
题目简述:
给你两个序列 $\{a_n\}$ 和 $\{b_n\}$,$q$ 次询问,每次询问都给出四个数 $l_1,r_1,l_2,r_2$,问重新排列 $a_{l_1},a_{l_1+1},\dots,a_{r_1}$ 后,排列后的这段序列是否与 $b_{l_2},b_{l_2+1},\dots,b_{r_2}$ 相等。
数据范围:

  • $1\le n,q\le 2\times 10^5$
  • $\forall i\in[1,n],1\le a_i,b_i\le n$
  • $1\le l_1,r_1,l_2,r_2\le n$

我们需要一个算法(或数据结构)来快速的判断两个序列是否相等,于是我们想到了哈希。
我们用前缀和求出 $\displaystyle suma_i=(\sum_{j=1}^ia_j^X)\bmod p$($X$ 是个常数,$p$ 是模数),$sumb$ 同理。
然后我们对于每次查询判断 $suma_{r_1}-suma_{l_1-1}$ 是否等于 $sumb_{r_2}-sumb_{l_2-1}$ 即可。
防止被卡,我们就跑一个四哈希。

时间复杂度为 $\Theta(n\log X+q)$。
代码

P4767 [IOI2000] 邮局 加强版 题解 \/ 四边形不等式优化 DP 学习笔记

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-18 21:11:36

P4767 [IOI2000] 邮局 加强版

题目考察:四边形不等式优化动态规划。
题目简述:
在一条线上有 $n$ 个村庄,现在要在 $m$ 个村庄上建邮局,使所有村庄到他们最近的邮局的距离之和最小,求距离和。
形式化题意:
给你 $\{a_n\}$,求:
$$\min_{1\le id_1<id_2<\dots<id_m\le n}(\sum_{i=1}^n \min_{j=1}^m(|a_i-a_{id_j}|))$$ 数据范围:

  • $1\le n\le 3000$
  • $1\le m\le 300$
  • $m\le n$
  • $\forall i\in[1,n],1\le a_i\le 10^4$

设状态 $f_{i,j}$ 为在前 $i$ 个村庄里已经建了 $j$ 个邮局的最小距离和,$w_{i,j}$ 为在第 $i$ 到 $j$ 个村庄中建一个邮局的最小距离和,转移方程为:
$$f_{i,j}=\begin{cases}0&i=0\ ee j=0\+\infty&(i=0\ ee j\ne 0)\wedge(i\ne 0\ ee j=0)\\min_{k=1}^{i-1}(f_{k,j-1}+w_{k+1,i})&\text{otherwise}\end{cases}$$ $$w_{i,j}=\begin{cases}0&i=j\\sum_{k=i}^j|a_k-a_{\lfloor\frac{i+j}{2}\rfloor}|&i\ne j\end{cases}$$ 证明 $1$:在第 $i$ 个村庄和第 $j$ 个村庄中建邮局选中点最合适:

  • $j-i+1$ 为奇数:
    选第 $\displaystyle\lfloor\frac{i+j}{2}\rfloor$ 个村庄建邮局是最优的,因为往右边建会使 $\displaystyle i\sim \lfloor\frac{i+j}{2}\rfloor$ 这些村庄去那里的距离加 $1$,剩下的会减 $1$,距离和会变大。
  • $j-i+1$ 为偶数:
    同上,第 $\displaystyle\lfloor\frac{i+j}{2}\rfloor$ 个村庄和第 $\displaystyle\lceil\frac{i+j}{2}\rceil$ 个村庄的距离和都是最小的。

综上,选第 $\displaystyle\lfloor\frac{i+j}{2}\rfloor$ 个村庄是没有问题的。

这样时间复杂度是 $\Theta(n^2(n+m))$,T 飞了。


我们发现求 $w_{i,j}$ 可以用前缀和实现,我们将小于中点和大于中点的村庄分开讨论,设 $sum_i=\sum_{j=1}^ia_j$(当然要排序),式子就变成了:
$$w_{i,j}=|a_{\lfloor\frac{i+j}{2}\rfloor}\times(\lfloor\frac{i+j}{2}\rfloor-i)-(sum_{\lfloor\frac{i+j}{2}\rfloor-1}-sum_{i-1})|+|(sum_j-sum_{\lfloor\frac{i+j}{2}\rfloor})-a_{\lfloor\frac{i+j}{2}\rfloor}\times (j-\lfloor\frac{i+j}{2}\rfloor)|$$ 这样时间复杂度是 $\Theta(n^2m)$,又 T 飞了。


正题开始

有一种 dp 叫四边形不等式优化动态规划。
证明 $2$:证明四边形不等式优化动态规划的正确性和时间复杂度:

  1. 四边形不等式的定义:
    设 $f_{x,y}$ 是一个函数,对于所有的 $a\le b\le c\le d$,都满足 $f_{a,d}+f_{b,c}\ge f_{a,c}+f_{b,d}$,则称其满足四边形不等式。
    特别地,若对于所有的 $i<j$,都有 $f_{i,j+1}+f_{i+1,j}\ge f_{i,j}+f_{i+1,j+1}$,则能推出其满足四边形不等式。
  2. 证明 $w_{i,j}$ 满足四边形不等式和单调性:
    • 证明四边形不等式:
      证明 $w_{i,j+1}+w_{i+1,j}\ge w_{i,j}+w_{i+1,j+1}$,我们要分别分解。
      因为我懒,分解的式子就不写了,最终结果就是这样的: 注:图中省略了一些距离,但结果相同。
    • 证明单调性: 区间包含 $w_{i+1,j}\le w_{i,j+1}$,显然成立。
  3. 证明 $f_{i,j}$ 满足四边形不等式:
    因为 $f_{i,1}=w_{1,i}$,所以当 $j=1$ 时满足。
    而后面 $f_{k,2}=f_{i,1}+w_{i+1,k}$,由于 $f_{k,2}$ 是由两个满足四边形不等式的函数相加得到的,所以他必然也满足四边形不等式,其实是我又懒了
    以此类推。
  4. 证明决策单调性($d_{i,j-1}\le d_{i,j}\le d_{i+1,j}$):
    我又懒了,感性理解就是建的邮局少了,最后的邮局就要往前建;距离远了,最后的邮局就要往后建。(不然就与最优矛盾了)
  5. 时间复杂度:
    $i=1$ 时,$k\in[d_{1,1},d_{2,2}]$。
    $i=2$ 时,$k\in[d_{2,2},d_{3,3}]$。
    ......
    长度累加等于 $p_{m+1,m}-p_{1,1}+n<2n-2$ 故时间复杂度为 $\Theta(n(n+m))$。

代码

P10053 [CCO2022] Bi-ing Lottery Treekets 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-22 12:58:19

P10053 [CCO2022] Bi-ing Lottery Treekets

题目考察:数论,组合数学,递推,树形 dp。
题目简述:
给定一棵有 $n$ 个结点的树,有 $k$ 个球,第 $i$ 个球将被投放在树上的 $x_i$ 号点上,但球的投放的顺序未确定,对于每次球被投放,他都会:

  1. 球刚被投放:
    • 若其左右儿子均没有球,则可以向任意方向往下滚。
    • 若左儿子或右儿子上有球,则向另一方向往下滚。
    • 若左儿子和右儿子上都有球,则结束行动。
    • 若该位置有球,则该方案不合法。
  2. 球是滚下来的:
    • 若其左右儿子均没有球,则向原来的方向往下滚。
    • 若左儿子或右儿子上有球,则向另一方向往下滚。
    • 若左儿子和右儿子上都有球,则结束行动。

定义 $ans_i$ 是最终落在 $i$ 号点上的球,没有则为 $0$,问最后的合法的 $ans$ 的个数对 $10^9+7$ 取模的结果。
数据范围:

  • $1\le n,k\le 4000$
  • $\forall i\in[1,n],1\le a_i\le n$

考虑树形 dp。

设 $f_{i,j}$ 为在 $i$ 号点上有 $j$ 个球落入了这里的合法方案数(这里的“落入”不含投放的球),那么我们枚举 $l$ 代表在投放在 $i$ 点的球中有 $l$ 个按照原来的方向往下落,这个转移方程需要含以下几部分:

  • 设在 $i$ 点上投放了 $a_i$ 个球,则我们需要在其中选出 $l$ 个球,即 $\displaystyle\binom{a_i}{l}$。
  • 设 $son_{i,0/1}$ 为 $i$ 点的左/右儿子,$vis=0/1$ 为他原本的方向:左/右,$b_i$ 代表在 $i$ 的子树内有多少点空着。则我们需要拿到 $vis$ 方向儿子上的方案数,则为:$f_{son_{u,vis},\min(j+l,b_{son_{u,vis}})}$,因为最多有 $\min(j+l,b_{son_{u,vis}})$ 个球按原来的方向往下落。
  • 我们还需要在往这边落的 $l$ 个球中排顺序,由于它是带顺序的,所以答案是 $l^{\underline{\min(j+l,b_{son_{u,vis}})}}$。
  • 我们统计右儿子的方案数的方法同上,但要注意可能有一个球停在 $i$ 点,故答案为 $f_{son_{u,[vis=0]},a_i+j-\min(j+k,b_{son_{u,vis}})-[j==b_i]}$。
  • 同上,我们也要排顺序,答案是 $(a_i-l)^{\underline{a_i+j-\min(j+k,b_{son_{u,vis}})}}$。

那么我们将上面的所有数相乘累加即可。

代码

[ABC368E] Train Delay 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-08-25 08:33:13

[ABC368E] Train Delay

题目考察:图论建模,思维,双指针。
题目简述:
有 $m$ 辆火车在 $n$ 个城市间穿梭,对于第 $i$ 辆火车,他会在 $s_i$ 时刻从 $a_i$ 城市出发,在 $t_i$ 时刻从到达 $b_i$ 城市。
现在第 $1$ 辆火车推迟了 $ans_1$ 单位时间,问在使得推迟总时间最小的情况下,怎样使原本可以换乘的火车现在还可以换乘(换乘不需要时间)。
数据范围:

  • $2\le n,m\le 2\times 10^5$
  • $\forall i\in[1,m],1\le a_i,b_i\le n,a_i\ne b_i$
  • $\forall i\in[1,m],0\le s_i<t_i\le 10^9$
  • $1\le ans_1\le 10^9$

要想直接跑拓扑的话,轻轻松松就卡成 $\Theta(n^2)$ 了,不可行。

那么我们发现瓶颈是在拓展以下式子而变慢的: $$ans_v=max(0,ans_u+t_u-t_v)$$ 但是我们发现,$ans_u+t_u$ 这部分都是一样的,那么我们可以将其记录在 $b_u$ 这个点上,当拓展这个式子时从这个点上取值计算就可以了。

当然,$t_u\le s_v$ 的才有贡献,那么我们复制一份火车时程表,一个按 $s_i$ 排序,一个按 $t_i$ 排序,跑一个类似于双指针的东西就可以了。

时间复杂度为 $\Theta(m\log m)$,瓶颈在排序。

代码

[ABC351E] Jump Distance Sum 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-04-28 15:30:30

题目

考察:思维。
题目简述:
定义 $\text{dist}(A,B)$ 表示:

  • 一开始它在 $A$ 点。
  • 设 $A$ 点坐标为 $(x,y)$,然后它可以向 $(x+1,y+1),(x+1,y-1),(x-1,y-1),(x-1,y+1)$ 移动一步,$\text{dist}(A,B)$ 为移动的最小步数。
  • 当其永远无法达到时,$\text{dist}(A,B)=0$。

给你 $n$ 个点,其坐标分别为 $A_i$,求 $\displaystyle\sum_{i=1}^{n-1}\sum_{j=i+1}^n\text{dist}(A_i,A_j)$。


我们很容易分析出 $\text{dist}((x_i,y_i),(x_j,y_j))=\max(x_i-x_j,y_i-y_j)$,在 $(x_i+y_i)\bmod 2\ne(x_j+y_j)\bmod 2$ 时,$\text{dist}((x_i,y_i)(x_j,y_j))=0$。
暴力模拟的话,时间复杂度为 $O(n^2)$,无法通过 $n\le 2\times 10^5$ 的数据。

我们可以尝试把他转化成曼哈顿距离,如图:
我们将其旋转 $45$ 度,使 $(0,0)$ 还是 $(0,0)$,这样 $(0,2)$ 变成了 $(-1,1)$。
我们很容易发现 $(x,y)$ 变成了 $\displaystyle(\frac{x_i+y_i}{2},\frac{y_i-x_i}{2})$。
以上是 $(x_i+y_i)\bmod 2=0$ 的情况,$(x_i+y_i)\bmod 2=1$ 时我们只需要让 $y_i$ 减去 $1$ 就可以了。

这样,式子就变成了 $\displaystyle\sum_{i=1}^{n-1}\sum_{j=i+1}^n|x_i-x_j|+|y_i-y_j|$,那么我们可以排一个序(值是不变的),然后: $$\sum_{i=1}^{n-1}\sum_{j=i+1}^nx_j+y_j-x_i-y_i=\sum_{j=2}^n\sum_{i=1}^{j-1}x_j+y_j-x_i-y_i$$ 然后我们可以维护前缀和($\displaystyle sumx_x=\sum_{i=1}^xx_i,sumy_x=\sum_{i=1}^xy_i$),这样:
$$\sum_{j=2}^n\sum_{i=1}^{j-1}x_j+y_j-x_i-y_i=\sum_{j=2}^n(j-1)(x_j+y_j)-sumx_{j-1}-sumy_{j-1}$$ 这样就可以了。

代码:

#include<bits\/stdc++.h>
#define int long long
#define inl inline
#define INF LLONG_MAX
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define rer(i,x,y,cmp) for(int i=x;i<=y&&cmp;++i)
#define per(i,x,y) for(int i=x;i>=y;--i)
#define FAST ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const int N=4e5+5;
int n,x[N],y[N],ans;
vector<int>gx[5],gy[5];
signed main(){
	FAST;
	cin>>n;
	rep(i,1,n) cin>>x[i]>>y[i];
	rep(i,1,n){
		int k=(x[i]^y[i])&1;
		gx[k].push_back((x[i]+y[i]-k)>>1);
		gy[k].push_back((y[i]-x[i]-k)>>1);
	}
	rep(i,0,1){
		sort(gx[i].begin(),gx[i].end());
		sort(gy[i].begin(),gy[i].end());
	}
	rep(k,0,1){
		int sumx=0,sumy=0,siz=gx[k].size();
		rep(i,0,siz-1){
			int x=gx[k][i],y=gy[k][i];
			ans+=x*i-sumx+y*i-sumy;
			sumx+=x;
			sumy+=y;
		}
	}
	cout<<ans;
	return 0;
}	

P6465 [传智杯 #2 决赛] 课程安排 讲解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-04-30 14:24:09

题目

考察:尺取法,桶。
题目简述:
给你长度为 $n$ 的一个序列 $c$,求序列中满足下列条件的子段 $[l,r]$ 个数:

  • 序列长度(即 $r-l+1$)$\ge k$(题目中的 $l$)。
  • 对于每个 $i$($l\le i<r$),$c_i\ne c_{i+1}$。
  • $c_l\ne c_r$。

$O(n^2)$ 暴力模拟肯定不行,我们可以往尺取法的方向想。

我们优先找到所有的 $c_i=c_{i+1}$ 的下标,将这个序列分段。
然后我们很容易发现,对于每个 $r$ 去找的合法的 $l$ 的个数,就是在 $r-k+1$ 之前 $l$ 的数量,减去等于 $c_r$ 的 $c_l$ 的数量。这两个数量都是很容易统计的,我们可以边做边维护桶。

这样基本就可以了,但是我们还要注意不能用 memset 清空桶。

代码:

#include<bits\/stdc++.h>
#define int long long
#define inl inline
#define INF LLONG_MAX
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define rer(i,x,y,cmp) for(int i=x;i<=y&&cmp;++i)
#define per(i,x,y) for(int i=x;i>=y;--i)
#define FAST ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const int N=5e5+5;
int t,n,a[N],f[N],pr[N],cnt,l,sum,ans;
inl void solve(){
	cnt=ans=0;
	cin>>n>>l;
	rep(i,1,n) cin>>a[i];
	pr[++cnt]=0;
	rep(i,2,n)
		if(a[i-1]==a[i]) pr[++cnt]=i-1;
	pr[++cnt]=n;
\/\/	rep(i,1,cnt) cout<<pr[i]<<endl;
	rep(i,2,cnt){
		sum=0;
		rep(j,pr[i-1]+l,pr[i]){
			++f[a[j-l+1]];
			++sum;
			ans+=sum-f[a[j]];
		}
		rep(j,pr[i-1]+l,pr[i]) f[a[j-l+1]]=0;
	}
	cout<<ans<<endl;
}
signed main(){
	FAST;
	cin>>t;
	while(t--) solve();
	return 0;
}	
共 127 篇博客