Initializing

Valuable Problems

题意

思路

点击查看题解

代码

P6503

题意

给出一个长度为 \(n\) 的序列 \(a_i\),求出下列式子的值:

\[\sum_{i=1}^{n}\sum_{j=i}^{n}(\max_{i\le k\le j}a_k-\min_{i\le k\le j}a_k) \]

\(n\le 3\times 10^5,a_i\le 10^8\)

思路

点击查看题解

考察:单调栈技巧

首先化简,变为

\[\sum_{i=1}^{n}\sum_{j=i}^{n}\max_{i\le k\le j}a_k-\sum_{i=1}^{n}\sum_{j=i}^{n}\min_{i\le k\le j}a_k \]

分别求值。

技巧:反向枚举:原本是枚举区间求最小值,现在枚举最小值求区间。

钦定区间最小值为 \(a_p\),求有那些区间满足条件。显然对于一个极大的区间 \([l,r]\),若其中最小值为 \(a_p\),则 \(l\le k\le r,a_k\le a_p\)\(a_{l-1},a_{r+1}>a_p\)。于是只需要求左边、右边最近的大于 \(a_p\) 的数的位置即可。

求出 \(l,r\) 后,答案则为

\[\sum_{p=1}^{n}a_p\times (i-l+1)(r-i+1) \]

其实还没完,对于相等的情况,可能有某个区间内有多个最小 / 大值。这样可能使答案偏大,为不重复计算,假定只有最左边那个极值能产生贡献。于是左端点 \(l\) 应是左边最近一个小 / 大于等于 \(a_p\) 的右边一个(左边不取等),右端点 \(r\) 应是右边最近一个小 / 大于 \(a_p\) 的左边一个(右边可以取等)。微调一下单调栈内不等号即可。

代码

https://www.cnblogs.com/chargedcreeper/p/17962041

https://www.luogu.com.cn/record/127429185

P6649

题意

\(n\times m\) 的网格从第 \(n\) 行走到第 \(0\) 行结束,可以往左、上、右走,但对于每一行,不能走到 第一次来到该行的位置 的右边。求得分最小值。

\(n,m\le 10^3,|a_i|\le 10^6\)

思路

点击查看题解

考察:dp,最小子段和。

可以发现对于每一行必然有:在这一行走到的最左边 \((i,j)\),走到下一行的位置 \((i,k)\),从上一行来到这一行的位置 \((i,l)\),同时 \(j\le k\le l\)

考虑设 \(dp(x,y)\) 表示现在在 \((x,y)\) 的最优解,发现无法转移:因为不知道第一次来该行的位置,可能走出不合法的路径。于是设 \(dp(i,k)\) 表示现在在 \((i,k)\) 准备走到下一行,此时的最优解。求出最小子段和 \((i,j)\sim (i,k)=\sum_{o=j}^{k}a(i,o)\),同时计算向后的最小子段和 \((i,k)\sim (i,l)+dp=dp(i+1,l)+\sum_{o=k}^{l}a(i,o)\)。相加即为答案。

代码

https://www.luogu.com.cn/record/135797772

P6812

题意

区间加,区间查询是否不降。

\(n,q\le 10^6,a_i\le 10^9\)

思路

点击查看题解

考察:线段树 / 树状数组

事实上题目对“区间查询是否不降”进行了包装,但很好看穿。

线段树可以直接做。树状数组更妙,维护差分数组,用树状数组维护差分数组非负性(\(0/1\))。查询时求差分数组是否全部非负即可。

代码

P7073

题意

给定一个只含 &|! 的后缀表达式,分别求改变每个变量后表达式的值。

思路

点击查看题解

考察:表达式树

典题,表达式树 + 是否短路(对表达式无贡献)。如果用栈模拟要结合暴力,可能会 T/M。

代码

暂无。

P7074

题意

\(n\)\(m\) 列方格图从左上角走到右下角,不能重复走一个方格,最大值路径上数的和。

思路

点击查看题解

考察:dp

只能考虑 dp。若设 \(dp(i,j)\) 表示从 \((1,1)\) 走到 \((i,j)\) 的最大和,可以发现无法保证不重复,无法转移。

考虑再细分状态。发现如果从 \((i-1,j)\) 走到 \((i,j)\),则不能往回走。也就是说,状态可以保存来时的方向,这样就能保证不重复。具体看代码。

代码

https://www.luogu.com.cn/record/165721514

P7167

题意

\(n\) 个圆盘从上到下排列,第 \(i\) 个圆盘直径为 \(d_i\),容量为 \(c_i\)。倒水时若当前圆盘满了,则流到下面第一个直径大于当前圆盘的圆盘。最下面是编号为 \(0\) 的水池,充分大。

给定 \(q\) 组互相独立的询问,第 \(i\) 次询问形如向第 \(r_i\) 个圆盘里倒入 \(v_i\) 的水,求水最后会流到哪一个圆盘停止。

\(n\le 10^5,q\le 2\times 10^5\)

思路

点击查看题解

考察:倍增单调栈

可以发现流水的关系是一棵树,可以使用单调栈求出。问题即转化成跳多少次父亲,使得路径上水被消耗完。

暴力跳不行,考虑倍增。用倍增数组求出点 \(i\) 向上跳 \(2^j\) 步跳到哪个点、途中消耗水量。询问时直接从大到小尝试 \(j\) 跳即可。细节小多。

代码

https://www.luogu.com.cn/record/129490916

P7913

题意

\(n\) 个廊桥分给国内、国际两部分。有 \(m_1\) 架国内飞机,\(m_2\) 架国际飞机,每架飞机有到达、离开时刻 \(a_i,b_i\)

廊桥先到先得,求分配的最优方案使得最多飞机停在廊桥。

\(n,m_1+m_2\le 10^5\)\(a_i,b_i\le 10^8\) 且互不相同。

思路

点击查看题解

考察:前缀和思维

先忽略廊桥数量的限制。维护一个空闲的廊桥队列,每到达一架航班,就给它安排编号最小的廊桥供其使用,求出每个廊桥停靠的飞机数 \(cnt_i\)

加上廊桥数量的限制,可以发现直接就解决了问题。枚举国内分配几个,求出国际有几个。对廊桥停靠的飞机数前缀和 \(s_i=\sum_{j=1}^{i}cnt_j\),代表停靠廊桥编号小于等于 \(i\) 的飞机个数,也即分配 \(i\) 个廊桥时停在廊桥的飞机数。国内、国际相加取最大值即为答案。

代码

https://www.luogu.com.cn/record/128834774

P7915

题意

给定一个长度为 \(2n\) 的双端队列 \(a\),其中 \(1,\dots,n\) 各出现 \(2\) 次。有一个空的 \(b\) 序列,每次将一元素从 \(a\) 出队(从开头或结尾均可)放入 \(b\) 末尾,要求 \(b\) 为回文序列,求字典序最小的操作方案。无解输出 \(-1\)

\(n\le 5\times 10^5\)

思路

点击查看题解

考察:注意力贪心

可以发现如果第一次取出 \(a\) 开头元素,则另一次出现该元素的位置一定是最后一个出队的,因为该元素需分别处于 \(b\) 的开头、结尾来实现回文。取出 \(a\) 结尾元素同理。

该元素另一个出现位置将 \(a\) 划分为两个栈,栈底分别为上述位置的两侧。

具体来说,若有 \(a_1=a_i\),则两个栈(栈底到栈顶)分别为:

  • \(a_{i-1}\sim a_2\)
  • \(a_{i+1}\sim a_n\)

\(a_n=a_j\) 同理:

  • \(a_{j-1}\sim a_1\)
  • \(a_{j+1}\sim a_{n-1}\)

问题转化为:每次从两个栈顶中选一个出栈,放入 \(b\) 末尾,使 \(b\) 回文。

类似的,注意到如果取出了某个元素 \(x\),则另一个 \(x\) 必须最后一个出栈。即 \(x\) 必须同时存在于栈顶和栈底(具体在哪个栈、是否在同一个栈并不重要)。这样,如果删去 \(x\) 对最优解没有影响。

于是,可以将栈改为双端队列,只需寻找这样的 \(x\),将它们两个同时出队,保存答案即可。如果找不到 \(x\) 则无解。如果有多个 \(x\) 取使字典序最小的。

第一个元素有两种取法,需分别求解。

代码

https://www.luogu.com.cn/record/158843287

P8059

题意

给定一棵 \(n\) 个点的树,每时刻都有边断裂(共 \(m\) 次),断裂后与根(\(1\) 号节点)不连通的部分称为在该时刻掉落。求每个点的掉落时间。

\(n\le 2\times 10^5,m\le 4\times 10^5\)

思路

点击查看题解

考察:正难则反dfs

连通性相关删边题目考虑正难则反,求出每个猴子第一次与 \(1\) 连通的时间。每次断裂(连接)时在子树中 dfs 打标记。

代码

https://www.luogu.com.cn/record/129895749

P8287

题意

\(k\) 个源点,每单位时间流沿边流动,求形成环的最短时间。

\(n\le 10^6,m\le 2\times 10^6,k\le 10^4\)

思路

点击查看题解

考察:二分并查集b/dfs

两种做法。

第一种是注意到答案有单调性,直接二分答案。预处理边满流的时间,对于当前子图判断是否有环(通过搜索)。可以使用并查集,但没必要。直接 dfs 判断是否有横插边/返祖边即可。

第二种运用 bfs + 并查集。bfs 过程中,

  • 若子状态未访问过,当前状态与子状态合并。(状态就是点。)
  • 反之若访问过,则检查是否为同一集合,
    • 同一集合则更新答案为 \(\max(dis_u,dis_v)\)
    • 反之合并二状态。

同时需维护 \(dis_u\) 表示 \(u\) 至源点最近距离(耗时)。

代码

https://www.luogu.com.cn/article/fuc7vj7c

https://www.luogu.com.cn/article/3slxhfa4

https://www.luogu.com.cn/record/130565732

P8675

题意

有一个 \(n\times m\) 的图纸,从下往上搭积木。每块积木必须紧挨着放置在某一块积木的正上方,最底层除外。同一层中的积木必须连续摆放,标有 X 的位置不能放置积木。求方案数。

\(1\le n,m\le 100\)

思路

点击查看题解

考察:区间 dp前缀和优化

对于每个方案,可以由 \((l_1,r_n)\dots,(l_n,r_n)\) 表示。\(l_i,r_i\) 分别表示第 \(i\) 层的左右端点。

自然的 dp:设 \(dp(i,l,r)\) 表示已摆了下面 \(i\) 层,第 \(i\) 层摆放为 \((l,r)\) 的方案数。转移方程:

\[dp(i,l,r)=\sum_{j=1}^{l}\sum_{k=r}^{m}dp(i-1,j,k)\qquad\text{(第 $i$ 层的 $[l,r]$ 没有 \texttt{X})} \]

边界

\[dp(0,1,m)=1 \]

答案即枚举搭 \(i\) 层,累加即可。

\[ans=\sum_{i=0}^{n}\sum_{l=1}^{m}\sum_{r=l}^{m}dp(i,l,r) \]

注意 \(i\)\(0\) 开始,即包括啥都不搭的方案。

代码实现略有不同。

代码

https://www.luogu.com.cn/record/126394295

P8815

题意

求仅含 &| 的逻辑表达式 \(s\) 的值和二运算符的短路次数(分别)。

\(|s|\le 10^6\)

思路

点击查看题解

考察:模拟

表达式求值,考虑栈模拟(其实没有栈)。

  • 如果前面已经短路,
    • 有左括号跳括号,跳完为止;
    • 若为右括号,则短路结束;
    • 如果为 0& 型短路且当前为 |,即 0&...|...,则有 0|...,短路结束;
    • 反之为 1| 型短路且当前为 &,即 1|...&...,则无关紧要;
    • 0& 型短路且当前为 &,即 0&...&...,直接丝滑小连招继续短路;
    • 1| 型同理。
  • 反之前面没有短路,则前面都没有影响,另起炉灶,
    • 若遇到数,则将值暂时置为该数;
    • 若有短路,则设置为相应短路状态。

代码

https://www.luogu.com.cn/record/125789473

P8733

题意

平面直角坐标系上 \(n\) 个点,每次从一个点走到另一个点时距离不能超过 \(D\)。求从 \(1\) 号点出发,途径所有点后回到 \(1\) 号点,所需最短距离。

\(n\le 20\)

思路

点击查看题解

考察:状压 DP最短路

发现 \(n\) 很小,果断状压。设 \(dp(i,S)\)\(i\in S\))表示当前在 \(i\) 点,已经过的点集为 \(S\),所需最短距离。

不难发现,最优路径必然是依照一个目标序列,向目标前进,不存在刻意重复到达某点的情况。

也就是说,转移时只需维护前驱 \(j\),使 \(j\to i\),转移方程为 \(dp(i,S)=\min\{dp(j,S\setminus\{i\})+dis(j,i)\}\)

\(j\to i\) 不一定能够直达,故需建图跑最短路,求出 \(dis(j,i)\)

代码

https://www.luogu.com.cn/record/139109514

P8801

题意

给定正整数 \(n=\overline{n_m\cdots n_0}\),可以对其任意一位 \(n_i\) 执行以下两种操作:

  1. \(n_i\gets (n_i+1)\bmod 10\)
  2. \(n_i\gets (n_i-1)\bmod 10\)

求最多进行 \(A\) 次操作 \(1\)\(B\) 次操作 \(2\) 后,\(n\) 的最大值。

\(m\le 18,A,B\le 100\)

思路

点击查看题解

考察:数位 dp暴力

最优解肯定是从高位到低位依次全部改成 \(9\)。但有两种选择,执行操作 \(1\) 还是操作 \(2\)

考虑数位 dp:从高位到低位直接 dfs,讨论使用哪种操作。时间复杂度 \(O(2^m)\)

代码

https://www.luogu.com.cn/record/141917725

P8805

题意

给定一棵树,点权为点的度数,进行若干询问,询问两点间路径上的点权和。

\(n,m\le 10^5\)

思路

点击查看题解

考察:LCA树上前缀和

典题了。维护 \(sum_i\) 表示根到 \(i\) 路径上点权和,设询问 \(u,v\)\(l=\operatorname{lca}(u,v)\),则 \(ans=sum_u+sum_v-sum_l-sum_{fa(l)}\)

P9209

题意

\(n\) 辆车按顺序停在 \(n\) 个停车位中,对于第 \(i\) 辆车,如果当时停放时左边有连续 \(l\) 个空位,右边有连续 \(r\) 个空位,那么它将需要 \(W_i-l\times L_i-r\times R_i\) 单位时间停放。求最小总耗时。

\(n\le 10^5\)

思路

点击查看题解

考察:贪心

最小化 \(W_i-l\times L_i-r\times R_i\) 即最大化 \(l\times L_i+r\times R_i\)。当 \(L_i\ge R_i\) 时发现应让 \(l\) 尽量大,即放在最右边,反之亦然。故每次只可能停最左和最右边。故停第 \(i\) 辆时,有 \(\max l/r=n-i\),直接计算即可。

答案为

\[\begin{aligned} ans&=\sum_{i=1}^{n}W_i-(n-i)\times\max(L_i,R_i)-0\times\min(L_i,R_i)\\ &=\sum_{i=1}^{n}W_i-(n-i)\times\max(L_i,R_i) \end{aligned} \]

代码

https://www.luogu.com.cn/record/126720348

P9364

题意

给定一个字符串集合 \(S\),找到最长字符串满足其所有子串都在 \(S\) 中,输出其长度。

\(n,\sum_{s\in S}|s|\le 10^5\)

思路

点击查看题解

考察:Trie/哈希排序注意力

注意到题目中要求子串,这包含原串本身,故答案字符串必定在 \(S\) 中。

同时,观察到对于任意长度为 \(n\) 的字符串 \(s\)\(s\in S\)\(s[1,n-1]\) 完美且 \(s[2,n]\) 完美 \(\iff\) \(s\) 完美。同时,定义空串完美。

故从短到长遍历 \(S\) 中字符串,依次判断是否完美即可。

代码

https://www.luogu.com.cn/record/127944157

P9474

题意

形式化地,你需要在元素互不相同的长度为 \(n\) 的数列 \(a\) 中选出一个长度为 \(m\) 的元素互不相邻的子序列,使得子序列的极差最小。

\(n\le 10^5,m\le \lceil n/2\rceil,a_i\le 10^9\)

思路

点击查看题解

考察:双指针思维

显然存在 \(O(n^2)\) 的暴力 dp 做法。

发现有 \(12\%\) 的数据,保证 \(a_i\) 单调递增,同时因为“不相邻”是一个相对弱的条件,考虑将 \(a_i\) 排序(需保留原下标)。可以枚举左端点,求最靠左的右端点,使得区间中可以组成合法子序列。

容易发现右端点是单调的,即若 \(l\) 的右端点为 \(r\),则 \(l+1\) 的右端点 \(r'\ge r\)

接下来考虑怎样快速求一段区间能组成的最长合法子序列长度。如果从值下手,此题类似于最大的独立集问题(即有若干互不相同的元素,有若干条件诸如某两个元素不可在同一集合内,求最大的集合大小。可以抽象成图。),很难下手。不妨换个角度:直接将当前区间内所有元素按原下标填入一个新序列中。新序列可能有位置空出,也有若干连通块。设各连通块长度为 \(L_i\),则最长合法子序列长度为

\[\sum_i\left\lceil\cfrac{L_i}{2}\right\rceil \]

例如:对于 \(a=[1,5,0,9,4,8]\),排序后 \(a'=[0,1,4,5,8,9]\)

对于 \(a'\) 上区间 \([2,4]\)(即 \([1,4,5]\)),以原下标填入 \(b=[1,5,\ ,\ ,4,\ ]\),肉眼可见有两个连通块。第一个连通块可以选出 \(\lceil 2/2\rceil=1\) 个数,第二个可以选出 \(\lceil 1/2\rceil=1\) 个数,相加即为 \(2\)

再比如区间 \([1,5]\)\([0,1,4,5,8]\)),填入 \(b=[1,5,0,\ ,4,8]\),最大长度为 \(\lceil 3/2\rceil+\lceil 2/2\rceil=2+1=3\)

“填入序列”可以使用类似珂朵莉树(ODT)的方法,维护若干现有区间。移动左端点时即删除左端点,看情况缩小区间或分裂。移动右端点即添加新右端点,看情况扩大区间或合并即可。

代码

https://www.luogu.com.cn/record/117195632

P9751

题意

\(n\)\(m\) 边有向图,第 \(i\) 边在时刻 \(a_i\) 出现,通过均耗时 \(1\) 单位时间。

\(k\) 的非负整数倍时刻从 \(1\) 号点出发、\(n\) 号点离开。不能在任何地方停留。

求最早离开时刻。无解输出 \(-1\)

\(n\le 10^4,m\le 2\times 10^4,k\le 100,a_i\le 10^6\)

思路

点击查看题解

考察:二分最短路分层图

此题显然不是简单的最短路。去除“边出现时刻”的限制,我们假定现在所有边都存在。

可以发现,由于边权均为 \(1\),最短路退化为 bfs。

同时由“\(k\) 的非负整数倍”这一表述(以及 \(k\le 100\) 的小范围),注意到对于两个状态(路径),如果他们的长度(耗时)在模 \(k\) 意义下同余,则它们重复了。即只需保留耗时更短的状态。因为对于耗时更长的状态,其接下来可能的行动都可以“移植”到耗时更短的状态上,从而被替代。

但是对于两个耗时在模 \(k\) 意义下不同余的状态,若其中一个状态有解或无解,与另一状态无关。因为它们的余数不同,可行的路径或是否无解也不一定相同。

于是在 bfs 判重的 vis 数组中,需要新增一维属于模 \(k\) 同余值。如果队头状态处于终点 \(n\),且耗时为 \(k\) 非负整数倍(即模 \(k\)\(0\)),则到达目标状态。

这相当于将每个点拆成 \(k\) 个,分别表示余数。

接下来考虑“边出现时刻”的限制。

一个做法是二分开始时间,按条件 bfs,对每次的耗时取 \(\min\)。这样做正确性比较难证。

另一种做法是二分结束时间倒推。

更好的做法:发现能在起点等 \(k\) 的非负整数倍相当于能在任意点等 \(k\) 的非负整数倍。转移时若时间未到,直接在原地等 \(k\) 的负整数倍时间直至可以通过。易证这样一定是最优的。注意到这样边权不全是 \(1\),跑 Dijkstra 即可。

代码

https://www.luogu.com.cn/record/134470526

? P10134

题意

\(n\) 头牛,每头牛有分数 \(c_i\) 满足 \(1\le c_i\le C\)。有 \(q\) 条限制条件,每条形如 \(h_j\) 为第一个严格大于前 \(a_j\) 头牛分数的牛(\(1\le a_j<h_j\le n\))。有一些分数被 FJ 忘了,求字典序最小的分数序列。多测。

\(n\le 10^5,C\le 10^9,T\le 20\)

思路

点击查看题解

考察:

https://usaco.org/current/data/sol_prob1_silver_jan24.html

我们定义 \(B(k)\) 为第一只严格大于前 \(k\) 只牛分数的牛的下标。这很有用,因为 FJ 的记忆限制可以表述为 \(B(a_i)=h_i\)。为了简化公式,我们同时设 \(pre_k=\max\limits_{1\le l\le k}c_l\),即前缀最大值。

对于 \(B\),我们显然有

  1. \(pre_i=pre_{B(i)-1}\)
  2. \(c_{B(i)}>pre_i\)

对于 \(\forall 1\le i<j<B(i)\),显然有 \(B(i)=B(j)\),反之可以证明矛盾。故如果存在两个限制 \(i,j\),满足 \(a_i<a_j<B(a_i)\land B(a_i)\ne B(a_j)\),无解。综上所述,对于任意 \(i\le j<B(i)=h_i\),我们可以得出 \(B(j)\) 的值(为 \(h_i\))。对于其他 \(B(j)\),我们称它们未知。

这足以使我们得出一个贪心的算法:枚举 \(i\)\(1\)\(n\),存储满足 \(B(1)\dots B(i)\) 约束条件 \(c_1\dots c_n\) 的最小值。

对于一个确定的 \(i\),如果 \(B(i)\) 未知,则无需操作。反之则有两种情况;

  1. \(pre_i=pre_{B(i)-1}\):可以发现这并没有对 \(c_i\) 施加额外的约束,因此我们不必修改它。\(c_{B(i)}\) 有一个相关的变化,我们将在下一个情况后讨论。
  2. 反之 \(pre_i<pre_{B(i)-1}\),我们需要找到一个 \(j\le i\) 并将 \(c_j\) 设为 \(pre_{B(i)-1}\)。但是,
    • 首先 \(j\) 需要尽可能大,且 \(c_j\) 不能被题目给定。因为我们希望答案的字典序尽可能小。
    • 其次不应存在 \(k\) 使得 \(j\le k\land B(k)<B(i)\)。否则修改后 \(pre_{B(i)-1}=c_j<c_{B(k)}\le pre_{B(i)-1}\),矛盾。
    • 因此如果不存在满足上述二条件的 \(j\),无解。

对于两种情况,我们都需要保证 \(c_{B(i)}>pre_i\)。若 \(c_{B(i)}\) 没有给出,则可设为 \(pre_i+1\)。反之若 \(c_{B(i)}\) 已经给出,我们需要保证它至少为此值(即满足 \(c_{B(i)}>pre_i\))。若无法满足,无解。

这种算法之所以有效,是因为每增加一个约束条件,就只能产生一个等价或更大的词典序列。因此,通过在数组中尽可能靠后的位置进行修改,得到的序列就是词典最小序列。最后,只需遍历序列,确保所有值小于等于 \(C\),以检查问题中的最后一个约束条件是否满足。

时间复杂度 \(O(n^2)\)https://www.luogu.com.cn/record/164344021。考虑优化。

第一部分即填写 \(B\) 可以使用双指针优化。具体的,枚举 \(1\le i\le n\),维护 \(j\),如果需要,则令 \(j\)\(i+1\) 移动 \(B(i)-1\) 填写。如果发现 \(j\) 需要倒退并填写不同的值,则无解。

第二部分即构造 \(c\)。可以发现如果满足了 \(B(i)\) 的条件,那么 \(B(i+1),\dots,B(B(i)-1)\) 都可以跳过。于是我们有了时间复杂度 \(O(n)\) 的算法:https://www.luogu.com.cn/record/165903355

代码

https://www.luogu.com.cn/record/164344021

https://www.luogu.com.cn/record/165903355

P10277

题意

\(k\) 名农夫面试 \(n+1\) 头牛。

时刻 \(0\)\(\forall 1\le i\le k\),农夫 \(i\) 面试奶牛 \(i\)。第 \(i\) 头牛面试花费 \(t_i\) 分钟。一旦一名农夫完成面试,他将立刻开始面试队列中的下一头奶牛。如果多名农夫同时完成,下一头奶牛可以根据自己的偏好选择接受任一此时空闲的农夫的面试,每头牛偏好未知。

求第 \(n+1\) 头牛面试开始时刻和可能面试她的农夫。

\(k\le n\le 3\times 10^5,t_i\le 10^9\)

思路

点击查看题解

考察:思维

由于每头牛面试的时间与选择那个农夫无关,故可以先求出每头牛面试的开始时间 \(beg_i\) 和结束时间 \(end_i=beg_i+t_i\)。解出第一问。

考虑哪些农夫可能面试第 \(n+1\) 头牛。

我们称一个时刻是重要的,当且仅当任意农夫在该时刻结束面试,便有机会面试第 \(n+1\) 头牛。

显然 \(beg_{n+1}\) 是重要的。其次,我们可以推出若时刻 \(i\) 是重要的,且 \(\forall j,end_j=i\),那么 \(i-t_j\) 也是重要的。因为我们可以通过面试第 \(j\) 头牛,实现在 \(i\) 时结束对牛 \(j\) 的面试。于是我们可以推出所有的重要时刻(或在重要时刻结束面试的牛)。

对于任意 \(1\le i\le k\),如果第 \(i\) 头牛在重要时刻结束面试,则第 \(i\) 名农夫有可能面试第 \(n+1\) 头牛。

代码

https://www.luogu.com.cn/record/153542044

P10278

题意

给定 \(P\) 个柱子的坐标,保证它们组成一个邻边互相垂直的多边形,且保证该多边形所有边互不相交。

给定 \(n\) 头牛的起点和终点坐标,保证在多边形上。牛有两种选择:往一边或另一边。牛会选择短的一边。牛经过(包括起点和终点)栅栏时会触碰栅栏。

求每个栅栏被触碰次数。

\(n\le 10^5,P\le 2\times 10^5,x,y\le 10^9\)

思路

点击查看题解

考察:模拟

离散化,从一个柱子开始建立多边形,即求出每个点的相邻顶点。

对于每头牛,分别求出起点和终点最近的两个柱子。破环为链,使用前缀和求出求出环上两种路径的长度,选择短的一条。

使用差分标记被触碰的栅栏。最后还原触碰次数并输出即可。

代码

https://www.luogu.com.cn/record/153949576

? P10308

题意

定义一次操作为同时将 \(a\) 中所有元素替换为 \(\bigoplus\limits_{j=1}^{i}a_j\)

进行 \(q\) 次单点修改,每次修改后,求出最小操作次数使得操作后与操作前序列 \(a\) 相同。答案对 \(10^9+7\) 取模。

\(n,q\le 3\times 10^5,a_i\le 10^9\)

思路

点击查看题解

考察:思维数学

显然对于一次操作,其等价于枚举 \(1\le i\le n,a_i\gets a_i\oplus a_{i-1}\)。类似于前缀和。

以下默认循环节为最短循环节。

题目即求循环节,考虑求出每一位的循环节后取 \(\operatorname{lcm}\)

posted @ 2024-07-04 11:34  Po7ed  阅读(7)  评论(0)    收藏  举报