NOI题目选做

P1224 [NOI2013] 向量内积

考虑枚举 \(i\),查询在 \(1\sim i-1\) 里面有没有满足条件的
首先看 \(k=2\) 的情况,如果 \(\vec{a_i}\cdot \vec{a_j}=1\) 对于任意 \(j<i\) 成立,那么 \(\sum_{j<i}\vec{a_i}\cdot \vec{a_j}\bmod 2=(i-1)\bmod 2\)
如果这个东西不等于 \((i-1)\bmod 2\),那么一定有一组,暴力找就可以
否则我们默认他没有
单次询问 \(\mathcal O(nd)\)
\(k=3\) 时虽然有 \(1,2\) 两种情况,但是注意到 \(1^2\bmod 3=2^2\bmod 3=1\),所以我们维护 \(\sum_{j<i}(\vec{a_i}\cdot \vec{a_j})^2\) 即可
\(\mathcal O(nd^2)\)
但是这样做显然不能保证正确性
所以我们random_shuffle,然后多跑几次就好了
code

P1399 [NOI2013] 快餐店

显然答案是 \(\min\{\operatorname{diam}\{T^\prime\}\}\),其中 \(T^\prime\) 是基环树 \(T\) 删掉环上的一条边得到的树
考虑首先把这个环给找出来
如果答案的直径不经过环,那么相当于是基环树每个节点上连着的子树上的直径的 max
如果答案经过环,我们枚举在哪里断开这个环
那么接下来的直径分成三种情况,假设我们把 \((p_k,p_{k+1})\) 断开
那么有 \(\max\{f_i+f_j+dis(i,j)\}\),其中 \(i,j\) 可能都在 \(p_k\) 左边,也可能都在 \(p_{k+1}\) 右边,也有可能两边一边一个
对于全在左边的情况,我们预处理前缀 \(f_j-dis_j\) 的最大值,就可以求了
全在右边同理
对于一遍一个的情况,我们预处理 \(f_i+dis_i\) 的前缀 max 和 \(f_i-dis_i\) 的后缀 min 就可以了
code

P1398 [NOI2013] 书法家

出的很好,下次不要出了
发现从左到右切开每个字母可以切成 9 部分,分别转移即可
code

P2305 [NOI2014] 购票

树上斜率优化模板题,首先考虑没有距离限制,那么可以直接可撤销单调栈维护凸包斜率优化,加上距离限制就是用个线段树套一下
但是有一个更美丽的做法,我们考虑每个点的 dfs出栈 序,然后再 dfs 一遍,求出 \(u\) 往上最远能调到 \(v\),那么 \([dfn_u,dfn_v]\) 这一段计算过的只有在 \((u,v)\) 这条链上的点,因此直接线段树维护凸包,不需要进行删除
另外这道题也可以有根树点分治,先递归重心往上走的子树,然后用重心往上走的链更新重心的子树
code

P2387 [NOI2014] 魔法森林

考虑把边按照 \(a\) 从小到大排序一次加入,如果 \((x,y)\) 此前已经联通,就删掉这条路径上 \(b\) 最大的那条边,利用 lct 不难维护
code

P2354 [NOI2014] 随机数生成器

首先那一坨随机数的东西根本就没用,说一堆来迷惑你(
首先 1 肯定要选,然后分成了左上和右下两个小矩形,但是这样复杂度还是很高
注意到我们可以直接维护每行每列可以选的边界是多少,也就是维护这些小矩形的边界,从小到大加入每个数,如果在边界里就选上,然后暴力更新边界,因为只会更新 \(O(n)\),每次的时间是 \(O(n)\),复杂度是平方的
code

P2150 [NOI2015] 寿司晚宴

经典题,注意到每个数最多有一个 \(\geq 23\) 的质因子,因此我们状压前 \(8\) 个质数的选的情况,按照每个数的最大的质因子的大小顺序 dp 即可
code

P2304 [NOI2015] 小园丁与老司机

第一问比较简单,是一个典型的 dp,发现除了往左往右走的边以外是一个 dag,同一层里面我们可以一个点拆四个点,分别是入点,同一层往右走的点,同一层往左走的点和出点,注意指向同一层往右走的点的时候需要把往左边能走到的也一起算上作为边权,然后就搞出来一个 dag,dag 上 dp,输出方案不难
第二问就是反图上再跑一个 dp,确定哪些点在最短路上,这些边就必须要选,然后跑一个有源汇有上下界最小流即可,主要是代码难写
code

P1173 [NOI2016] 网格

/tuu
显然答案小于等于 2,等于 0 就是原图本身不连通,等于 1 就是原图有割点
不连通好判断,只需要对于每个黑点的八连通块的八连通的白点是四联通的即可
割点如何判断呢,如果只取八联通的话会被这样的数据卡掉

WBW
WWW
WWW

\((2,2)\) 这里的白色点会被搞成割点
解决方法是取周围的 \(24\) 个点,但是这样同样会出现问题

WWWWB
WWWWW
WWWWW
WWWWW
BWWWW

这个时候 \((3,3)\) 又成了割点了
解决方法是注意到只有挨着黑点的白点可能是割点,所以我们取 \(24\) 个,但是只 check 和黑点八连通的白点是否是割点
现在的代码可以过 uoj 的数据
code

P1587 [NOI2016] 循环之美

首先问题转化为 \(\sum_{i\leq n,j\leq m}[\gcd(i,j)=1][\gcd(j,k)=1]\)
然后套路莫比乌斯反演拆式子,太长了自己推,最后杜教筛 mu 的前缀和
NOI之前记得重新推一遍
code

P1721 [NOI2016] 国王饮水记

神仙题,计划写个题解
upd:咕了,因为发现最后一部分并没搞懂证明,大概就是猜一猜结论然后斜优

P3822 [NOI2017] 整数

线段树维护压位高精度,进退位线段树二分找到全0/1的区间,然后区间推平,注意线段树二分复杂度别写假了(uoj上会T)
code

P3823 [NOI2017] 蚯蚓排队

链表维护,哈希,暴力 \(k^2\) 修改,非常 naive
code

posted @ 2021-06-20 15:46  YuukiYumesaki  阅读(62)  评论(0编辑  收藏  举报