NOI2022联合省选 题解
day1的题解咕咕咕了,有空再写吧(好吧,看到这么长的题面+大模拟就没有写题解的欲望了……

注:非官方题解,不保证绝对正确,做法不一定是官方做法

注2:代码请见这篇blog

d2t1:传送门https://www.luogu.com.cn/problem/P8292
题意:给定一些数字,每次询问一些质数,要求从给定的数字中选出一个子集,使得乘积被所有询问的质数整除,求方案数。
数据范围:n≤106,m≤1500,∑ci≤18000n\leq 10^6, m \leq 1500, \sum c_i \leq 18000n≤106,m≤1500,∑ci​≤18000,值域范围 200020002000 。
sol:注意到这么大的 nnn 其实没用(只要统计每种数有多少个就行了),同样 mmm 的范围其实也没什么用,决定复杂度的其实是 ∑ci\sum c_i∑ci​ 和值域范围。
对于这道题而言,一个数的影响显然只与它的质因子集合有关,因此你可以把所有质因子集合相同的数合并,不过这其实并不本质,因为仍然会剩下 120012001200 多个数。
200020002000 的值域范围很耐人寻味,我们可以观察得到这么一个性质:由于 43×47=2021>200043\times47=2021>200043×47=2021>2000 ,因此一个数最多只会包含一个 ≥43\geq 43≥43 的质因子。而 <43<43<43 的质数一共只有 131313 个。
假设我们根本不关心那些 <43<43<43 的质因子(比如,如果询问里没有的话),那这题就很简单了:把所有数按照含有哪个 ≥43\geq 43≥43 的质因子进行分类(可能包含某一个,也可能不含),设每一类有 aia_iai​ 个数,那么对于一类而言,如果询问集合里包含这一类的质因子的话,就代表这一类的数至少要选一个,方案数是 2ai−12^{a_i}-12ai​−1 ;否则就是可以任意选,方案数是 2ai2^{a_i}2ai​ 。把每类的方案数乘起来即可。
现在要把前 131313 个质因子考虑进来,于是我们可以大力容斥:枚举 {前 131313 个质因子} ∩\cap∩ 询问集合 的子集,要求所选的数里必须不包含这个子集中的质因子。然后只需要把不符合条件的数扔掉之后重复刚才只考虑 ≥43\geq43≥43 的质因子的情形就行了。
总复杂度 O(213∑ci)O(2^{13}\sum c_i)O(213∑ci​) ,看起来不小但实测跑得飞快。

d2t2:传送门https://www.luogu.com.cn/problem/P8293
题意:给定一个括号序列,,每个左括号有一个权值。你有如下操作:一是把 (A)(B) 变成 (A()B) ,代价为 x×(A)x \times (A)x×(A) 中第一个左括号的权值 $ + y \times (B)$ 中第一个左括号的权值,其中 x,y∈0,1x,y \in {0,1}x,y∈0,1 ;二是把 AB 变成 BA ,无代价。问把原串变成 (((...()...))) 的最小代价。
sol:仔细观察题目中的操作,发现其实答案只与每个括号在哪一“层”有关。操作一的本质是花一定的代价把一对括号扔进里层,我们总是可以从外到里操作,这样操作到某一层时,这一层里的所有括号就可以用操作二进行任意交换。
用vector记录每层的数,每次操作一可以进一步抽象为“用一个数(即 (A) 中第一个左括号的价值)把另一个数(即 (A)中第一个左括号的价值)放进里层”。下面我们称 (A) 中第一个左括号的价值为“辅助”。
根据 x,yx,yx,y 的不同可能的取值分类讨论:
如果 x=1,y=1x=1,y=1x=1,y=1 :假设当前层有 mmm 个数,最大值是 mxmxmx ,最小值是 mnmnmn ,总和是 sumsumsum ,那么无论是最终被放进去的还是留在外面的至少都要有一次的代价,同时总的代价次数一定是 2(m−1)2(m-1)2(m−1) ,那么显然可以贪心地用最小的数当辅助,把多出来的 m−2m-2m−2 次代价全都算在 mnmnmn 头上。同时放尽可能小的数进去使得下一层尽可能小,只需最后用最大的数把最小的数放进去。代价为 (m−2)×mn+sum(m-2)\times mn+sum(m−2)×mn+sum 。
如果 x=0,y=1x=0,y=1x=0,y=1 :这种情况也很简单,因为代价只与被放进去的数有关,那么就每次贪心地把尽可能小的数往里扔就行了。每一层把最大的数留在外面,这一层的代价为 sum−mxsum-mxsum−mx 。
最复杂的情况是 x=1,y=0x=1,y=0x=1,y=0 ,即代价算在辅助头上的情况:对于每一层,首先要决策把哪个数留下来,然后用最小的数把其余的数放进去,最后再用留下来的数把最小的数放进去。问题是如何决策呢?
计算所有层的总代价,我们发现除了最里层的数以外,每个数都会在某一层被留下来并计算一次贡献。既然这样,如果我们确定了最里层的数是多少,每一层就可以贪心地留下当前层的(除了要被放进最里层的数以外的)最大数,因为这样可以让尽可能小的数往里走,以减小里层辅助的代价。
很自然的想法是最里层放全局最大数,这样的决策如下:
当还没有遇到全局最大数时,留下本层最大,代价为 mn×(m−2)+mxmn\times (m-2)+mxmn×(m−2)+mx ;遇到了全局最大数时,留下本层次大,代价为 mn×(m−2)+cdmn\times (m-2)+cdmn×(m−2)+cd ( cdcdcd 为本层次大值)。
这就完了吗?我们发现存在反例:

1 10
9 9

如果第一层把全局最大值 101010 放进去,总代价为 1+9+9+9=281+9+9+9=281+9+9+9=28 ;但如果把 111 放进去,代价为 10+1+9+1=2110+1+9+1=2110+1+9+1=21 。问题出在哪里?
在于“遇到全局最大数后把当前层的次大值留下”这一步。如果这一层恰好只有 222 个数,而被留下的恰好是一个很小的数,就失去了把它放进里层用来当辅助的机会。
不过仔细分析,发现这种情况只可能出现在一开始,即第一层只有两个数的情况(如果第一层只有一个数,显然可以直接忽略这一层,从下一层开始做)。这是因为每层都只会留下一个数,而题目性质保证了每层至少也会多出来一个数,因此如果进入某一层时已经有超过 222 个数,一直到最后一步之前都一定是超过 222 个数。
于是我们可以在一开始遇到这种情况时特判把较小的数放进去,但是紧接着又会有问题:如果下一层只有 111 个数,可能又会面临刚才的尴尬情况。进一步,如果我们面临如下情况:前 kkk 层分别有 2,1,1,...2,1,1,...2,1,1,... 个数, 我们显然不能在每一层都枚举。
进一步,我们把这前 kkk 层一起处理,发现无非只有两种可能:要么把这 kkk 层的最大值扔进里面,用于扔进最里层;要么把这 kkk 层的最小值扔进里面,用于当里层的辅助。无论哪种情况这 kkk 层的代价均为所有数的和减去被放进去的数。
因此只要讨论这两种情况,后面按照原策略贪心即可。
总复杂度 O(nlog⁡n)O(n \log n)O(nlogn),瓶颈主要在于排序和/或用set维护当前层的最值。

d2t3:传送门https://www.luogu.com.cn/problem/P8294
题意:给定树,点有点权。每次切断一条边,交换这条边两个端点的点权,代价为这两个点权之和。求把所有边都切断的最小代价。
sol:第一种dp方案:设 f[x][y][z]f[x][y][z]f[x][y][z] 表示点 xxx 的子树,把子树内的点 yyy 换出去, 外面的 zzz 换进来的答案。
转移:考虑与 xxx 相邻的 333 条边的操作顺序:
1、如果先操作 xxx 与父亲的边,则被换出去的是 xxx ,枚举换进来的点 zzz 。假设剩余两条边先操作左子树,那么在左子树里枚举换出去的点 www ,把它换到 xxx 的位置之后换进右子树,枚举换出去的点 ppp ,则有: f[x][x][z]=min(f[x][x][z],f[lc][w][z]+f[rc][p][w]+c[x]+c[z])f[x][x][z]=min(f[x][x][z], f[lc][w][z] + f[rc][p][w] + c[x] + c[z])f[x][x][z]=min(f[x][x][z],f[lc][w][z]+f[rc][p][w]+c[x]+c[z]) 。剩余两条边先操作右子树同理。
2、如果先操作 xxx 与左儿子的边,则左子树换进来 xxx ,枚举换出去的点 www ;假设再操作 xxx 与父亲的边,那么换出去 www ,枚举换进来的 zzz ;最后把 zzz 换进右子树,枚举换出去的点 ppp ,则有: f[x][w][z]=min(f[x][w][z],f[lc][w][x]+f[rc][p][z]+c[z]+c[w])f[x][w][z]=min(f[x][w][z],f[lc][w][x] + f[rc][p][z] + c[z] + c[w])f[x][w][z]=min(f[x][w][z],f[lc][w][x]+f[rc][p][z]+c[z]+c[w])。
3、如果先操作 xxx 与左儿子的边再操作 xxx 与右儿子的边,那么要把 www 换进右子树,枚举换出去的点 ppp ;最后把 ppp 换出去,枚举换进来的点 zzz ,则有:f[x][p][z]=min(f[x][p][z],f[lc][w][x]+f[rc][p][w]+c[z]+c[p])f[x][p][z]=min(f[x][p][z],f[lc][w][x] + f[rc][p][w] + c[z] + c[p])f[x][p][z]=min(f[x][p][z],f[lc][w][x]+f[rc][p][w]+c[z]+c[p])。
4,5:如果先操作 xxx 与右儿子的边,与2,3同理。
虽然看起来枚举很多,但是复杂度是 O(n3)O(n^3)O(n3) 的,这是因为所有的操作可以归结为:枚举点 xxx ,并从左子树、右子树、子树外各枚举一点。众所周知枚举左右子树的点是 O(n2)O(n^2)O(n2) 的(类似于树形背包,只在lca处算贡献),再加一个子树外就是 O(n3)O(n^3)O(n3) 的。
但是这一算法也没法进一步优化了,因为状态本身已经 O(n3)O(n^3)O(n3) 了。
我们需要换一种状态!现在设 f[x][v][d]f[x][v][d]f[x][v][d] 表示点 xxx 的子树内, vvv 被换出去,被换进来的点最终停在距离 xxx 为 ddd 的位置上的答案。并且不计入换进来的点产生的贡献。
我们先看状态数:注意到 vvv 和 ddd 一定不会来自同一侧,因此套用树形背包可知状态数已经是 O(n2)O(n^2)O(n2) 的了 。
同样分类讨论转移:
1、先操作 xxx 与父亲 :假设再操作左儿子,则换进来的点最终停在左侧。那么枚举右侧深度 d′d'd′ ,左侧换出来的点 vvv 以及右侧换出来的点 v′v'v′,有: f[x][x][d]=min(f[x][x][d],f[lc][v][d−1]+f[rc][v′][d′]+c[v]×(d′+1)+c[x])f[x][x][d]=min(f[x][x][d],f[lc][v][d-1]+f[rc][v'][d']+c[v]×(d'+1)+c[x])f[x][x][d]=min(f[x][x][d],f[lc][v][d−1]+f[rc][v′][d′]+c[v]×(d′+1)+c[x]) 。再操作右儿子同理。
2、先操作左儿子再操作父亲:则换进来的点最终停在右侧。枚举左侧深度 d′d'd′ ,左侧换出去的点 vvv ,右侧换出去的点 v′v'v′ ,有: f[x][v][d]=min(f[x][v][d],f[lc][v][d′]+c[x]×(d′+1)+f[rc][v′][d−1]+c[v])f[x][v][d]=min(f[x][v][d],f[lc][v][d']+c[x]×(d'+1)+f[rc][v'][d-1]+c[v])f[x][v][d]=min(f[x][v][d],f[lc][v][d′]+c[x]×(d′+1)+f[rc][v′][d−1]+c[v]) 。
3、先操作左儿子再操作右儿子:则换进来的点最终停在 xxx 处。枚举左侧深度 d′d'd′,左侧换出去的点 v′v'v′ ,右侧深度 ddd ,右侧换出去的点 vvv ,有: f[x][v][0]=min(f[x][v][0],f[lc][v′][d′]+c[x]×(d′+1)+f[rc][v][d]+c[v′]×(d+1)+c[v])f[x][v][0]=min(f[x][v][0],f[lc][v'][d']+c[x]×(d'+1)+f[rc][v][d]+c[v']×(d+1)+c[v])f[x][v][0]=min(f[x][v][0],f[lc][v′][d′]+c[x]×(d′+1)+f[rc][v][d]+c[v′]×(d+1)+c[v]) 。
4,5:先操作右儿子,与2,3同理。
乍一看枚举的复杂度直接飞起,别急,让我们冷静分析:
1、先枚举 vvv ,然后不难发现无论 ddd 是多少,f[rc][v′][d′]+c[v]×(d′+1)f[rc][v'][d'] + c[v] × (d'+1)f[rc][v′][d′]+c[v]×(d′+1) 这一部分的贡献是可以独立计算的。因此先枚举 v′v'v′ 和 d′d'd′ ,计算 tmp=min{f[rc][v′][d′]+c[v]×(d′+1)}tmp=min\{f[rc][v'][d'] + c[v] \times (d'+1)\}tmp=min{f[rc][v′][d′]+c[v]×(d′+1)} ,再枚举 ddd 更新 f[x][x][d]f[x][x][d]f[x][x][d] 即可。
其中,计算 tmptmptmp 时先枚举 d′d'd′ ,由于 f[rc][v′][d′]f[rc][v'][d']f[rc][v′][d′] 这一项与先前枚举的 vvv 无关,因此可以在枚举 vvv 之前先预处理这一项关于每个 d′d'd′ 的最小值,因此在真正计算 tmptmptmp 时就无需再枚举 v′v'v′ 了;
分析这一步的代价:预处理时枚举 v′,d′v',d'v′,d′ 的代价受到 f[rc][v′][d′]f[rc][v'][d']f[rc][v′][d′] 有效的项数限制,是 O(n2)O(n^2)O(n2) 的;计算 tmptmptmp 时枚举的 v,d′v,d'v,d′ 来自不同子树,是 O(n2)O(n^2)O(n2) 的 ;最后计算 f[x][x][d]f[x][x][d]f[x][x][d] 时枚举的 v,dv,dv,d 的代价受到 f[lc][v][d−1]f[lc][v][d-1]f[lc][v][d−1] 的有效项数限制,是 O(n2)O(n^2)O(n2) 的。
2、 枚举 v,dv,dv,d ,注意到 f[lc][v][d′]+c[x]×(d′+1)f[lc][v][d']+c[x]×(d'+1)f[lc][v][d′]+c[x]×(d′+1) 与 ddd 无关, f[rc][v′][d−1]f[rc][v'][d-1]f[rc][v′][d−1] 与 vvv 无关,因此可以事先预处理出前者对于每个 vvv 的最小值和后者对于每个 ddd 的最小值,然后在计算 f[x][v][d]f[x][v][d]f[x][v][d] 时就无需枚举 d′,v′d',v'd′,v′ 了。利用相似的分析方法可以得到这一步的代价也是 O(n2)O(n^2)O(n2) 。
3、先预处理 f[lc][v′][d′]+c[x]×(d′+1)f[lc][v'][d']+c[x]×(d'+1)f[lc][v′][d′]+c[x]×(d′+1) 对每个 v′v'v′ 的最小值,再枚举 ddd ,然后先枚举 v′v'v′ 求出在当前这个 ddd 下 f[lc][v′][d′]+c[x]×(d′+1)+c[v′]×(d+1)f[lc][v'][d']+c[x]×(d'+1)+c[v']×(d+1)f[lc][v′][d′]+c[x]×(d′+1)+c[v′]×(d+1) 的最小值,最后枚举 vvv 计算 f[x][v][0]f[x][v][0]f[x][v][0] 即可。这一步也是 O(n2)O(n^2)O(n2) 。
最终,总的时空复杂度均为 O(n2)O(n^2)O(n2) 。

NOI2022联合省选 题解相关推荐

  1. 【NOI2019十二省联合省选】部分题简要题解

    Day 1 T1 异或粽子 题意:给出一个长为n的序列,选择K个不完全重合的区间使得每个区间的异或值的总和最大. 题解:先做一个前缀异或和,对于每一个右端点我们记录三元组(l,r,x)表示在左端点在\ ...

  2. [ 联合省选 2020 A | B ] 冰火战士 题解

    题目 学校里面写这道题的时候洛谷炸了,自己搞出来了. Part 0 记当前温度为 T T T ,小于等于 T T T 火战士能量和为 f 1 ( T ) f1(T) f1(T) , 大于等于 T T ...

  3. 集美大学第七届天梯赛校选题解

    目录 赛事总结 题目方面 出题组 难度把控 模拟程度 L1 基础级 L1-1 最菜的 算法思路 代码实现 L1-2 复读机 思路 代码实现 L1-3 JMU仓颉再现--绝绝子的何式汉字 题意 解题思路 ...

  4. 联合省选 JSOI 2021 游记

    提高组蒟蒻来被吊打啦. Day -3 首次写点分树,AC得很艰难. 刚了几道 dp 神题,口胡了 B 卷. Day -2 把一些不熟悉的板子打/复习了一遍,口胡了一场 Div.1+Div.2 CF(写 ...

  5. 联合省选 2021 解题报告

    很久没有写过博客了呢. 文章目录 D1T1 - 卡牌游戏 D1T2 - 矩阵游戏 D1T3 - 图函数 D2T1 - 宝石 D2T2 - 滚榜 D2T3 - 支配 B卷D1T1 - 数对 B卷D2T1 ...

  6. 联合省选2022游记

    Day 0 昨晚将某谷头像换成了麻美桑,顺势奶一波学姐: 身体好轻,怀着这么幸福的感觉战斗还是第一次 体が軽い,こんな幸せな気持ちで戦うなんて初めて 已经没什么好怕的了 もう何も怖くない 因为我不再是 ...

  7. 2017 多校联合训练 3 题解

    Problem 1003 维护一个链表 链表中记录大于等于x的数 一开始链表中插入所有的数 从小到大枚举x 用双指针从左到右跳k次 做完一个x删除这个节点 1 #include<iostream ...

  8. NOI 2021 游记题解总结

    文章目录 Travel Notes Day 0 Day 1 Day 3 Day 3.5 Day 10 Solutions D1T1 D1T2 算法一 算法二 Lemma D1T3 算法一 算法二 算法 ...

  9. Goodbye,OI!

    开始的开始,我们都是孩子 最后的最后,渴望变成天使 站在中科院计算所的玻璃门前,我静静等候着代晨昕.玻璃门不时拉开,来来往往的人们纷纷通过,可这扇门并不是为我敞开的.回头望去,外面的树木光秃秃的,街上 ...

最新文章

  1. 旅游网站的主页代码_一个在优化的网站主页内容应该如何设计?
  2. 数据结构与算法JavaScript描述——使用队列
  3. TCP、UDP和HTTP详解
  4. python 递归函数_连载|想用Python做自动化测试?递归函数
  5. 送书 | 日读论文100+,AI都替代不了!辞去医药研发总监后,她成为了一名全职学术警察...
  6. 相对路径 ‘’,‘/’,‘./‘,‘../‘
  7. asp.net 报表页面模板_Stimulsoft ASP.NET MVC报表教程:在设计器中保存报表模板
  8. 剑指offer之二叉搜索树的第K个结点
  9. 如何通过Chrome中的代码设置JavaScript断点?
  10. WebService 分布式事务怎么控制
  11. 快逸报表数据库密码加密解决方案
  12. iOS实现一个简单的视频播放器
  13. minimax算法_如何通过使用minimax算法使Tic Tac Toe游戏无与伦比
  14. 觅鹿影视在线解析源码带后台
  15. 从GDPR和个保法看,为什么要做数据合规?
  16. matlab中ode指令,在Matlab中使用ODE选择步长
  17. mymps蚂蚁分类信息模板二次开发调用标签
  18. 通过写n本书的积累,我似乎找到了写好技术文章的方法(回复送我写的python股票电子书)
  19. 计算机新生导论感言,大学生感言与寄语新生
  20. 清除文件用其他应用默认打开方式

热门文章

  1. 模拟IIC——关于模拟IIC的IO口的配置选取推挽输出还是开漏输出,以及是否需要更改IO口输入输出模式和是否需要对IO配置上拉
  2. SpringBoot——Banner介绍
  3. MSCOMM串口控件在VS2010中的使用
  4. html中的圆周率如何调用,谁算出来的圆周率
  5. 小米刷机OTA、 Recovery、 FASTBOOT三种方法直接的区别和联系
  6. nginx: [warn] conflicting server name 这里是域名 eg:abc.com on 0.0.0.0:80, ignored解决方法
  7. MFC添加界面的背景图片方法总结
  8. 移动端html尺寸,移动端页面的三种尺寸
  9. C语言编程:三(n)子棋游戏
  10. IDEA Eval Reset 使用方法