JOISC 2022 简要题解

版刷 JOISC 的计划就这么结束了。

鸽了许多题,懵懵懂懂过来的,兴奋的开始,中途得知省选没了,又鸽了一段时间。

好歹是完结了,撒花撒花。总体上题目质量很高,很开心以及荣幸有机会能感受 JOISC 的魅力。

update on 2022.12.4:重修也撒花了,算是对省选那段时间的纪念!

「JOISC 2022 Day1」监狱

  • 给定 \(n\) 个点的树上 \(m\) 个人的行走路线,形如 \(s_i\to t_i\),保证任意两个人的起点或终点均不相同。
  • 每次可以让某个人走到相邻点,但是不能存在一个点同时存在 \(\geq 2\) 个人。
  • 判断是否存在方案满足每个人的行走。
  • \(m\leq n\leq 1.2\times 10^5\)

核心性质:总存在一种解,是每次选一个人从起点持续移动到终点,并从此不再移动他。

也就是一个人走一下再等一下是不优的,具体画图更加直观,基于树无环这一基本条件,停下来等总不能对自己的移动有什么帮助。

那么容易建出一个 \(m\) 条路径之间的有向图,\(s_j\)\([s_i,t_i]\) 上那么 \(j\to i\)\(t_k\) 在路径上的则 \(i\to k\)。只需要判定是否连出来个 DAG。

一开始的思路是树剖 + 线段树优化建图,复杂度是 \(O(n\log ^2 n)\) 的,时空都不是很优秀。

实际上,树链的形态是能够用树上倍增更好的迎合的,只要直接倍增优化建图就能够 \(O(n\log n)\)

「JOISC 2022 Day1」京都观光

  • 给定 \(n\times m\) 的网格图,边权为:
    • \((i,j)\to (i,j+1)\) 需要花费 \(a_i\) 的代价。
    • \((i,j)\to (i+1,j)\) 需要花费 \(b_j\) 的代价。
  • 求从 \((1,1)\to (n,m)\) 的最小代价。
  • \(n,m\leq 10^5,a,b\leq 10^9\)

感觉可以当作典型模型。

考虑一个最小单元格:

	b_l   b_r
a_i --- - ---
	 |     |
a_j --- - ---
     |     |
a_k --- - ---

考虑从 \((i,l)\to (k,r)\),发现有三种路径:

  • \((i,l)\to (i,r)\to (k,r)\),代价为:\((r-l)a_i+(k-i)b_r\)
  • \((i,l)\to (j,l)\to (j,r)\to (k,r)\),代价为:\((j-i)b_l+(r-l)a_j+(k-j)b_r\)
  • \((i,l)\to (k,l)\to (k,r)\),代价为:\((k-i)b_l+(r-l)a_k\)

如果第 \(j\) 行想要有用,就一定要有 1, 3 的代价都 \(>\) 2 的,移项化简得到:

\[\frac{a_i-a_j}{i-j}<\frac{b_l-b_r}{l-r}<\frac{a_j-a_k}{j-k} \]

也就是说,如果 \(\frac{a_i-a_j}{i-j}>\frac{a_j-a_k}{j-k}\),不等式必然不成立,\(j\) 也就没用,对应于有用 \((i,a_i)\) 一定构成斜率递增的下凸壳!

实际上,容易发现有用的 \(a_i\) 一定是前后缀 \(\min\),但是下凸壳无疑是更强的限制。

此时可以先处理出 \(a,b\) 分别的下凸壳。

之后,如果已知 \(j\) 没用,那么考虑剩下两条路径的代价,只有 \(\frac{a_i-a_k}{i-k}<\frac{b_l-b_r}{l-r}\) 时,第一条路径更优,会优先往右走。

结合凸包经典结论,能够想到直接对两个做闵可夫斯基和,每次选择斜率更小的方向走即可。

「JOISC 2022 Day1」错误拼写

  • 给定字符串,长度钦定为 \(n\),定义 \(s_i\) 表示去掉第 \(i\) 位后的长度为 \(n-1\) 的字符串。
  • 给出 \(m\) 条限制 \((x,y)\),表示字典序 \(s_x<s_y\)
  • 求有多少种字符集为小写字母的满足所有限制的字符串。
  • \(n,m\leq 5\times 10^5\)

简单转化,假设 \(l=\min(x,y),r=\max(x,y)\),那么:

  • \(x<y\),表达的就是 \((l,r]<[l,r)\)
  • \(x>y\),表达的就是 \([l,r)<(l,r]\)

发现都是相邻位的比较,设 \(c_i\) 表示 \(\text{compare}(i,i+1)\in\{>,<,=\}\)

那么表达的就是 \([l,r)\) 中的第一个不等号是 \(>/<\),或者没有不等号。

从一个位置开始的同种限制显然保留右端点最大的。

不同限制可以考虑截取 \(\min\) 为全都是等号,然后更长的段放到后面限制,也可以直接分开考虑。

都很好转移,直接倒着 DP,将限制放到 \(l\) 上,每次枚举第一个和自己不同的下一位置转移。

对应不能转移的,就把对应点的状态去掉,发现就是 \(\leq \lim\) 的状态,直接开个小根堆,相当于只有一段后缀能转移。

「JOISC 2022 Day2」复制粘贴 3

  • 构造长度为 \(n\) 的目标串,初始 \(X\) 为空,支持三种操作:
    • 输入 \(c\),即 \(X\gets X+c\)
    • 剪切,将 \(X\) 剪切到剪切板 \(Y\),并令 \(X\) 为空。
    • 粘贴,即 $X\gets X+Y
  • 分别有代价 \(A,B,C\),求得到目标串的最小代价。
  • \(n\leq 2500\)

区间 DP。

最简单的是第一种操作,\(f(l,r)\gets f(l,r-1)+A\)

然后发现如果选择剪切 & 粘贴,肯定是粘贴次数越多越好,粘贴得到的字符串形如 ..Y....Y.YY..Y...

也就是说,中间有需要用 \(A\) 填补的缝隙,但总体是能粘贴就粘贴。

考虑前后缀都有边角字符不好处理,再添加转移 \(f(l,r)\gets f(l+1,r)+A\),那就可以默认 Y 为开头/末尾。

考虑对于 \(f(l,r)\) 刷表式的贡献到以 \(r\) 为右端点的串,预处理每个位置前一个最近的不重叠相同串,就可以简单得到。

对于同样 \(r\) 的串,只会调和级数的枚举转移,所以总复杂度是 \(O(n^2\log n)\) 的。

「JOISC 2022 Day2」团队竞技

懒得写题解,随便写点数据结构维护就没了。

「JOISC 2022 Day3」洒水器

  • 支持树上所有距离某个点 \(\leq d\) 的点乘 \(x\),单点查询,取模但不一定是质数。
  • \(n\leq 2\times 10^5,q\leq 4\times 10^5,d\leq 40\)

保证了 \(d\leq 40\) 就不用写点分树了,类似的直接容斥。

问题是不一定有逆元,暴力一点预处理拆模数的质因子,质因子之外的正常做,质因子的指数直接加减就能做除法了。

然后我辛辛苦苦写了个 \(O(qd\log d\log P)\),就常数大了点,怎么就能无情的卡到 \(53\text{pts}\) 呢/ll

实际上正解很朴素,直接对每个位置开 \(f(u,d)\),表示距离它为 \(d\) 的儿子需要乘的量。注意根上面需要建 \(d\) 个虚点。

每次往上跳 \(d\) 次,每次对 \(f(u,d)\)\(f(u,d-1)\) 都乘对应量。然后发现,无论奇偶深度的儿子,该乘的都乘上了,也不会多乘。

代码就 10 行,神奇,巧妙,可以当作典型模型。

「JOISC 2022 Day3」蚂蚁与方糖

  • 维护数轴上 \(m\) 次两种事件:
    • 位置 \(x\) 出现了 \(k\) 只蚂蚁。
    • 位置 \(x\) 出现了 \(k\) 个方糖。
  • 每只蚂蚁能唯一匹配恰好一个离自己不超过 \(L\) 的方糖,每次操作吼,求最大匹配。
  • \(m\leq 5\times 10^5,L,x,k\leq 10^9\)

考虑扩展 Hall 定理:

\(N(S)=\{y\mid \exist x\in S,(x,y)\in E\}\),则:

\[\text{maxmatch} = n-\max_s( |s|-|N(s)| )=\min_s(n+|N(s)|-|s|) \]

对于 蚂蚁和方糖存在的位置奇偶性不同且 \(L=1\) 的部分分,每个 \(N(\{x\})\) 就是和它相邻的点。

经典的把贡献放到相邻位置上可以轻松的用线段树 merge。

正解需要更多性质。

  • 性质一:设 \(\text{next}_s(i)\) 表示 \(i\)\(s\) 中的后继节点(按照坐标位置升序排序),那么 \(N(s)=\sum_{i\in s} |N(i)|- |N(i)\cap N(\text{next}_s(i))|\)

因为每个点的匹配点是一个以它为中心的定长值域区间,所以有这个性质,每个 \(y\) 会在最右边的和它右边的 \(i\) 处被统计到。

  • 性质二:若 \(l,r\in s\),且 \(x_r-x_l\leq 2L\),那么 \(\forall i\in[l,r]\),有 \(i\in s\)

如果有 \(i\in [l,r]\) 但不在 \(s\) 中,那么直接加入进来会在不影响 \(|N(s)|\) 的情况下增大 \(|s|\),显然更优。

  • 性质三:结合上两条性质,如果 \(N(i)\cap N(\text{next}_s(i))\neq \varnothing\),那么 \(\text{next}_s(i)=i+1\)

因为有交距离一定 \(\leq 2L\),所以有这个性质。

也就是说,每次维护对 \(|N(i)\cap N(\text{next}_s(i))|\) 交的容斥任然可以放到线段树的 merge 时的相邻点上。因为是最小化所以如果该减的没减一定不优。

考虑每次操作,如果是插入蚂蚁相当于单点修改 \(|s|\)

如果是插入方糖,设 \([l,r]\) 是与方糖右边的极大区间,那么相当于:

  • \([l,r]\)\(|N(i)|\) 区间加 \(k\)
  • \([l,r)\)\(|N(i)\cap N(\text{next}_s(i))|\) 区间加 \(k\)

前面的好办,后面则发现会对区间的答案 \(+tk\),其中 \(t\in\{0,1\}\)

取决于 \([l,r]\) 中是否有 \(\in s\) 的连续段(根据性质二,这个长度 \(\leq 2L\) 的区间至多包含一个连续段!)。

可以对 \([0/1,0/1]\)\(+k\),再特殊考虑 \([0,0]\gets \min([0,0],0)\),相当于特判全都不选。于是就能完美维护了!

「JOISC 2022 Day4」一流团子师傅

  • 交互题。
  • 给定 \(n\times m\) 个团子,有 \(n\) 种,每种恰好 \(m\) 个。
  • 要求给出 \(m\) 个大小为 \(n\) 的集合,使得每个集合取遍所有种类,每个团子只在恰好一个集合出现。
  • 每次询问可以给出一个团子集合,回答的是这些团子能组成至多几个那种集合。
  • \(n=400,m=25\),询问次数要求 \(\leq 50000\)

考虑直接维护 \(m\) 个集合,对每个团子,找到第一个没有它这种颜色的集合,放进去即可。

判定很简单,直接将全集排除 \([1,\text{mid}]\) 集合里的数,以及当前的团子,并查询。

如果 \(\text{Query}=m-\text{mid}-1\),说明 \([1,\text{mid}]\) 里确实人手一个这种团子,那么就 \(l\gets \text{mid}+1\),否则 \(r\gets \text{mid}\)

复杂度严格 \(nm\log m\),刚好卡满哈哈。还有一种 random_shuffle 再类似循环展开优化 \(O(nm^2)\) 的做法,挺奇妙的。

「JOISC 2022 Day4」复兴计划

  • 对于 \(n\) 个点 \(m\) 条边的带权无向图,每次询问给出 \(x\),此时边权定义为 \(|x-w|\),求最小生成树。
  • \(n\leq 500,m\leq 10^5,x,w\leq 10^9\)

核心性质:对于每条边,它被选择时的 \(x\) 一定是一段连续的区间。

考虑绝对值函数是 V 形的,且斜率相同,当某条边被取代说明有更优决策,因为两个 V 至多有 \(1\) 个交点,所以一定是一个连续区间。

考虑对每条边维护这个区间,将边从小到大排序后,因为 \(n\) 很小,直接在上一次最小生成树的基础上,去掉最大的环边即可,\(O(mn\alpha(n))\)

那么这条环边和当前边是势不两立的,对于 \(x=\) 它们的平均值开始,往左是选择这条环边,往右是选择当前边。

得到每条边的 \([l_i,r_i]\) 后,直接差分拆贡献,直接维护一次函数的前缀和即可。

posted @ 2022-12-04 22:51  LPF'sBlog  阅读(1221)  评论(2编辑  收藏  举报