HNOI 2018 Day1 题解

Luogu4424 [HNOI/AHOI2018]寻宝游戏

给出一个含有 n 个数的二进制数组 a1,a2,...,an,和 q 个长度也为 m 的二进制数 r1,r2,...,rq

在保持数组 a1,a2,...,an 的元素顺序不变下,你可以在它们之间插入 (按位与运算)或者 (按位或运算)。

你需要插入 n 个运算符,相邻两个数之前恰好一个,在第一个数的左边还有一个。如果我们在第一个运算符的左边补入一个 0,这就形成了一个运算式,我们可以计算它的值。与往常一样,运算顺序是从左到右。现在,对 r1,r2,...,rq 中的每一个值 ri,分别计算出有多少种方法填入这 n 个计算符,使的这个运算式的值是 ri ,模 1000000007

n1000,m5000,q1000


  排序 位运算 结论

  考试的时候,想到了从后往前,对于 ,如果是该位是 0,那么就会全变成 0 类似,然后就打了一个记搜,开了 O2 跑得飞快 (对于前 70 分可以 0.5s 完美通过),然后考到一半发现没有 O2,然后就 * 10 倍常数,就是 5 秒了,卡了卡常,成了 2s,但是时限 1s,直接裂开

  其实正解就是继续往下想,但是我想不到

  这个限制很像字典序,于是我们可以倒着考虑,对于某一位,我们把 n 个数的这一位拆下来,拼成一个长为 n01a(后面的作为高位),然后我们操作串为 b(同样,后面的作为高位,如果为 ,那么就是 0,否则为 1),然后我们进行字典序比较,在对于第一个位置 i,aibi,如果 ai0,那么这一位就是 0 了,否则就是 1 了,于是我们最后的操作串的字典序 < a 那么就是 1,否则为 0

  于是我们对于每条询问,就会有 m 个关于操作串的限制,我们只要确定左右端点,然后就是这里面的串都能选了。

  代码

Luogu4425 [HNOI/AHOI2018]转盘

一个转盘上有摆成一圈的 n 个物品(编号 1n),其中的 i 个物品会在 Ti 时刻出现。

0 时刻时,小 G 可以任选 n 个物品中的一个,我们将其编号为 s0。并且如果 i 时刻选择了物品 si,那么 i+1 时刻可以继续选择当前物品或选择下一个物品。当 sin 时,下一个物品为物品 1,否则为物品 si+1。在每一时刻(包括 0 时刻),如果小 G 选择的物品已经出现了,那么小 G 将会标记它。小 H 想知道,在物品选择的最优策略下,小 G 什么时候能标记所有物品?

但麻烦的是,物品的出现时间会不时修改。我们将其描述为 m 次修改,每次修改将改变其中一个物品的出现时间。每次修改后,你也需求出当前局面的答案。对于其中部分测试点,强制在线。

n105


  数据结构 线段树 单调栈

题解

  看到循环走,几乎弃疗了,然后啥也不太会推了,完美复现 NOI2021D2T2 被假 gcd 难住。

  首先有一个结论:

一定不要循环走,待在原地等物品出现是最优的。

  于是我们考虑时间倒流,假设终止时间是 0,那么答案就是所有拿到物品的时间最大值,断环成链,假设以 i 为起点,时间就是 max{Tj+n(ji)1},于是要求 mini{maxij{Tj+n(ji)1}},设 ai=Tii,那么就是维护 mini{maxij{aj+i}}+n1,然后我们考虑在 i 处计算贡献,同时我们发现,j 一定是一个后缀最大值,考虑线段树维护,那么每次 pushup 的时候,我们要知道当前位置的后缀 max,这个可以转移和楼房重建很像,于是可以类似地维护当最大值就在当前节点中,而不依赖外部传入的最大值时后的答案,每次 pushup 的复杂度就是 O(logn),总复杂度为 O(nlog2n)

  代码

启示

  1. 千万不要弃疗,一定要注意有什么东西是在糊弄人的!
  2. 这种 minmax 的式子可以想一想前缀 or 后缀 max,然后可以考虑楼房重建这种经典题(为什么考了几次这个技巧还是不会啊啊)

Luogu4426 [HNOI/AHOI2018]毒瘤

给出一张联通图(mn+10),求独立集方案数。

n105


  动态规划 虚树

题解

  突然有 NOI2021D1T3 的感觉。

  整场考试最有体验感的题目,靠着暴力获得了 80 分的好成绩,虽然离正解只差一步了

  我们将非树边标号,显然,我们可以设 fx,0/1,s 表示以 x 为根的子树,x 是否选择,目前 s 集合中的边已经有节点被占用了,这样转移的时候可以枚举子集,复杂度 O(n3mn+1),空间复杂度 O(n2mn+1),时空都爆炸。

  然后我们将非树边涉及的点称为关键点,于是注意到,如果一个子树里面都没有关键点,那么是对于整个集合都没有影响的,于是没有必要 DP 2mn+1 的值,于是我们可以保留关键点,建立虚树,每次转移的时候可以处理一下虚树上的边的系数,那么复杂度就降为 O(2(mn+1)3mn+1) 了。

  好像别的题解直接枚举每条边的情况再 DP?但是我是直接保留的,其实没有太大区别,具体实现的时候,可以动态申请空间,又因为虚树只要求一遍,于是我们可以 O(n) 地建立虚树以减少代码量。

  代码

启示

  1. 当有用的点较少的时候一定要想起虚树!
posted @   Werner_Yin  阅读(71)  评论(9编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示