0
点赞
收藏
分享

微信扫一扫

近期刷题总结 [19 03 24]

书呆鱼 2022-08-16 阅读 57


目录

​​CF14D Two Paths [树的直径]​​

​​P3174 [HAOI2009]毛毛虫 [树的直径]​​

​​P2312 解方程 [秦九韶算法]​​

​​CF888D Almost Identity Permutations [ DP ]​​

​​CF888G Xor-MST [0/1 trie]​​

​​CF863D Yet Another Array Queries Problem [ splay 模板 ]​​

​​P3700 [CQOI2017]小Q的表格 [ 毒瘤推式子+phi + 分块 ]​​

​​P3698 [CQOI2017]小Q的棋盘 [ 贪心 ]​​

​​P3747 [六省联考2017]相逢是问候 [ 线段树 + 扩展欧拉定理 + 均摊复杂度分析]​​

​​CF1065F Up and Down the Tree [ 树形DP ]​​

​​P3569 [POI2014]KAR-Cards [ 贪心 + 线段树维护决策 ]​​

​​P2607 [ZJOI2008]骑士 [基环树DP模板]​​

​​P3962 [TJOI2013]数字根 [st表]​​

​​P3964 [TJOI2013]松鼠聚会 [ 切比雪夫转曼哈顿]​​

​​P3961 [TJOI2013]黄金矿工 [ 有依赖背包 ]​​

​​P3761 [TJOI2017]城市 [ 树的直径 ]​​

​​P3199 [HNOI2009]最小圈 [分数规划+spfa]​​

​​P4067 [SDOI2016]储能表 [数位DP]​​

​​P4103 [HEOI2014]大工程 [ 虚树 ]​​

​​BZOJ3514 [LCT + 主席树] ​​

​​BZOJ5016 [莫队]​​

​​CF14D Two Paths​​ [树的直径]

枚举断边, 然后分别求直径

​​P3174 [HAOI2009]毛毛虫​​ [树的直径]

考虑点的个数不好考虑, 转换一下思路变成边呢 ? 点的个数就是边的个数+1

近期刷题总结 [19 03 24]_线段树

 

 其中 d 为度数, 然后点权作为d[i] - 1 跑直径

​​P2312 解方程​​ [秦九韶算法]

发现对一个或两个大质数取模冲突概率很低

然后有 

近期刷题总结 [19 03 24]_线段树_02

于是可以O(k) 求f(x) , 然后枚举就可以了, 复杂度O(mk)

​​CF888D Almost Identity Permutations​​ [ DP ]

f[i][j] 表示1--i 有j个不在应有位置上的个数

考虑第i+1位, 令i+1位填i+1, 如果不与前面交换, f[i][j] += f[i-1][j]

如果与前面一个不在应有位置的交换, f[i][j] += f[i-1][j-1] *  (j-1)

如果与前面一个在应有位置的交换, f[i][j] += f[i-1][j-2] * (i-j+1)

​​CF888G Xor-MST​​ [0/1 trie]

由于异或的特性, 异或值大小取决于二进制下相同位置0/1值相同的数量

最小代价就是相同的多, 所以可以看成两颗子树的合并。

所以我们设置一个siz数组, 若根的两端都有节点就进行合并:

枚举siz小的子树中的所有数, 到另一个子树中查找最小异或和, 更新答案

​​CF863D Yet Another Array Queries Problem​​ [ splay 模板 ]

​​P3700 [CQOI2017]小Q的表格​​ [ 毒瘤推式子+phi + 分块 ]

近期刷题总结 [19 03 24]_最长链_03

然后惊讶地发现

近期刷题总结 [19 03 24]_子树_04

因为  

近期刷题总结 [19 03 24]_子树_05

, 所以   

近期刷题总结 [19 03 24]_子树_06

这不就是GCD吗

近期刷题总结 [19 03 24]_最长链_07

近期刷题总结 [19 03 24]_最长链_08

近期刷题总结 [19 03 24]_子树_09

然后需要写一种数据结构要求单点修改f, 并查询前缀和, 因为查询前缀和是套在整除分块里面的, 所以应该做到O(1)

而修改可以O(sqrt(n)), 分块维护前缀和就可以了

​​P3698 [CQOI2017]小Q的棋盘​​ [ 贪心 ]

最开始走第一条链的时候每一步多一个节点, 否则需要下去上来两次才能多一个

然后第一次走最长链就可以了

​​P3747 [六省联考2017]相逢是问候​​ [ 线段树 + 扩展欧拉定理 + 均摊复杂度分析]

线段树维护已算次方的最小值, 如果区间最小值都大于需要的最小值( 模到phi[p] = 1的次数 )就不用开了

​​CF1065F Up and Down the Tree​​ [ 树形DP ]

g[i] 表示能回来的, f[i] 表示回不来的

近期刷题总结 [19 03 24]_最长链_10

近期刷题总结 [19 03 24]_子树_11

​​P3569 [POI2014]KAR-Cards​​ [ 贪心 + 线段树维护决策 ]

发现一个点如果小的能接到前面用小的更优

于是线段树记录小的大的在上右端点最小是多少

​​P2607 [ZJOI2008]骑士​​ [基环树DP模板]

​​P3962 [TJOI2013]数字根​​ [st表]

发现每个数的数字根就是它模9 (0 为 9)

预处理每个点与后面最近的哪个点中间的所有数和起来为0--8

询问时枚举每个数字根, 然后查l-r之间所有数的后面那个点在不在区间内, 在就可以作为答案

​​P3964 [TJOI2013]松鼠聚会​​ [ 切比雪夫转曼哈顿]

(x, y) 变成 ( x+y / 2, x - y / 2), 然后前缀和一波就可以了

​​P3961 [TJOI2013]黄金矿工​​ [ 有依赖背包 ]

​​P3761 [TJOI2017]城市​​ [ 树的直径 ]

枚举断边, 发现答案要么是一头的直径, 要么是另一头的直径, 要么是两边各选一个点, 使这个点到任意一点的最大距离最小

我们定义这个距离为半径r, 直径为d, 就是(d1, d2, r1+r2+w)取一个max

我们考虑一件事,就是距离它最远的那个点,在它的子树内还是子树外。

如果在子树内,距离就是第一遍dfs求出的最长链,如果在子树外的话,

我们在树上在做第二遍dfs,这个dfs额外传一个from参数,from表示这个子树之外的最长链

那么这个最长链from有两个来源

1.它父亲的from+它和父亲的距离

2.它父亲的其他子树中的最长链+他和父亲的距离

对于情况二,如果他就是父亲的所有孩子中的最长链,那么我们的情况2要取次长链,如果不是取最长链就可以了。

然后枚举每个点,半径就是min(max(dp[i],from[i]))了

​​P3199 [HNOI2009]最小圈​​ [分数规划+spfa]

二分一个答案然后判负环就可以了

​​P4067 [SDOI2016]储能表​​ [数位DP]

近期刷题总结 [19 03 24]_最长链_12

​​P4103 [HEOI2014]大工程​​ [ 虚树 ]

建出虚树后统计答案, 考虑每条边的贡献 -> dis * siz[son] * (tot - siz[son])

然后维护Min, Max 表示到子树中的关键点最小, 最大

如果该店是关键点, ans = min(ans, Min), ans = max(ans, Max), 并且将Min设为0

如果不是的话, 最小值就是(Min[son] + dis + Min[u]), 可以形象地理解为最小+次小

​​BZOJ3514​​ [LCT + 主席树] 

近期刷题总结 [19 03 24]_最长链_13

​​BZOJ5016​​ [莫队]

近期刷题总结 [19 03 24]_子树_14

 

举报

相关推荐

0 条评论