近期刷题总结[ 19 04 21 ]

40 篇文章 0 订阅
14 篇文章 0 订阅

目录

P2056 [ZJOI2007]捉迷藏 [括号序列 + 线段树] 

P3857 [TJOI2008]彩灯 [ 线性基 ]

P4570 [BJWC2011]元素 [ 贪心 + 线性基 ]

P5304 [GXOI/GZOI2019]旅行者  [ dijsktra ]

P5303 [GXOI/GZOI2019]逼死强迫症 [ DP + 矩阵乘 ] 

P5300 [GXOI/GZOI2019]与或和 [ 按位处理+单调栈 ]

P2116 城墙 [ 凸包 ]

P3292 [SCOI2016]幸运数字 [ 倍增 + 线性基 ]

P4322 [JSOI2016]最佳团体 [ 分数规划 + 树形DP ]

P2714 四元组统计 [ 组合数学 + DP ]

P3204 [HNOI2010]公交线路 [ 状压DP + 矩阵乘法 ]

P3239 [HNOI2015]亚瑟王 [ 概率DP ]

P3242 [HNOI2015]接水果 [ 整体二分 ]

P3226 [HNOI2012]集合选数 [状压DP]

P3214 [HNOI2011]卡农 [ 组合数学 + DP ]

P3250 [HNOI2016]网络 [整体二分]

P3246 [HNOI2016]序列 [ 莫队+单调栈 ]

P5290 [十二省联考2019]春节十二响 [ 堆 + 启发式合并 ]

P4332 [SHOI2014]三叉神经树 [LCT]

P2173 [ZJOI2012]网络 [LCT]

P5305 [GXOI/GZOI2019]旧词 [LCT]

P3265 [JLOI2015]装备购买 [线性基 + 高斯消元]

P5292 [HNOI2019]校园旅行 [ Spfa ]



P2056 [ZJOI2007]捉迷藏 [括号序列 + 线段树] 

https://blog.csdn.net/zxyoi_dreamer/article/details/88725891

我们考虑利用DFS出的括号序列来处理距离。

将点的编号塞到括号序列里面,那么两个点的距离就是它们中间的括号序列的非匹配括号数。


P3857 [TJOI2008]彩灯 [ 线性基 ]

我们每插入一个数, 就看它能不能被已有的数异或出来, 如果不能, 就插入线性基并记录个数加一

最后每个数都可以选或不选, 答案就是 2 ^ 个数


P4570 [BJWC2011]元素 [ 贪心 + 线性基 ]

有一个比较明显的贪心, 就是从大到小排序, 每插入一个数, 看它能不能被之前的数异或出来(不合法)

合法就加上它的值就可以了


P5304 [GXOI/GZOI2019]旅行者  [ dijsktra ]

考虑每一条边(x,y)的贡献, 就是w[i] + 离x最近的兴趣点 + 离y最近的兴趣点 (两个点不相同)

于是跑两遍dijsktra预处理就可以了, 如何跑 (将所有兴趣点加入队列并且dis设为0)

用from表示到距离最近的那个兴趣点的编号, 如果一个点x能更新另一个点y的最短路, 就将y的from[y] = from[x]


P5303 [GXOI/GZOI2019]逼死强迫症 [ DP + 矩阵乘 ] 

用 f(i, 0/1/2) 表示到i, 前面有0/1/2个

然后就是矩阵乘


P5300 [GXOI/GZOI2019]与或和 [ 按位处理+单调栈 ]

 我们按位处理, 每次就是一个0/1 矩阵, 如果是 &, 就是求全部为1的矩阵个数

我们用单调栈维护已(i, j)为右下角的矩阵个数

for(int j=1; j<=n; j++){
	res += h[j];
	while(top > 0 && h[j] <= h[sta[top]]){
		res -= (sta[top] - sta[top-1]) * (h[sta[top]] - h[j]);
		top--;
	} sta[++top] = j; sum += res;
}

具体来说就是总的减去不合法的

| 就是求至少有一个1的个数, 用总的减去全为0的就可以了


P2116 城墙 [ 凸包 ]

求凸包然后外层加一圈圆


P3292 [SCOI2016]幸运数字 [ 倍增 + 线性基 ]

倍增合并线性基, 然后类似LCA将所有线性基合并, 最后贪心求最大


P4322 [JSOI2016]最佳团体 [ 分数规划 + 树形DP ]

很容易想到分数规划, 然后在树上做一个背包就可以了


P2714 四元组统计 [ 组合数学 + DP ]

 


P3204 [HNOI2010]公交线路 [ 状压DP + 矩阵乘法 ]


P3239 [HNOI2015]亚瑟王 [ 概率DP ]

Ans = \sum_{i=1}^nd_i*g_i

gi 为 第i张牌发动的概率, 问题转化为求gi

首先有g1 = 1 - (1 - pi) ^ r , 就是1 - 从头到尾不发动的概率

考虑概率DP, f[i][j] 表示前i张牌, 发动了j张的概率

该张不发动

f[i][j] = f[i-1][j]*(1-p[i])^{r-j}

该张发动

f[i][j] = f[i-1][j-1]*(1-(1-p[i])^{r-j+1})

g_i=\sum_{j=0}^{i-1}f[i-1][j]*(1-(1-p[i])^{r-j})


P3242 [HNOI2015]接水果 [ 整体二分 ]

发现如果x, y不在一条链上, 那么只有  st_x<=l_i<=ed_x,st_y<=r_i<=ed_y  的i才有贡献

如果在一条链上, 那么  1<=l_i<=st_x-1,or,ed_x+1<=li<=n , st_y<=r_i<=ed_y 的i有贡献

问题转化为矩阵加, 单点查值, 整体二分, 按x排序, 扫描线就可以了


P3226 [HNOI2012]集合选数 [状压DP]

如果我们将每个数的2倍和3倍写在它的右边和下面, 那么有如下矩阵

\bigl(\begin{smallmatrix} 1& 3 &9 \\ 2& 6& 18\\ 4& 12& 36 \end{smallmatrix}\bigr)

合法的就是两两不相邻的, 状压DP计数就可以了


P3214 [HNOI2011]卡农 [ 组合数学 + DP ]


P3250 [HNOI2016]网络 [整体二分]

首先可以二分一个答案ans, 将所有>=ans的路径加入, 如果全部经过某点,  说明最大值还要变小

整体二分过后, 就变成了路径修改, 单点查值, 用dfs序维护一下就可以了


P3246 [HNOI2016]序列 [ 莫队+单调栈 ]

莫队一般考虑从(l, r)的答案变成(l,r+1)的答案, 多出来的就是

\sum_{i=l}^rMin(i,r+1)

我们令l -- r+1 中的最小值的位置为 P, 那么 l -- P的贡献就是 val[P], 这个可以RMQ求出来

我们现在要求p+1 -- r+1 之间的答案, 不妨设为 f[p+1][r+1], 考虑求f[l][r]

令 第一个小于r的地方为 pre(r), 那么pre(r) -- r 之间的答案都是 val[r]

于是有 f(l,r)=f(l,pre_r)+(r-pre_r)*val_r

把l的那一维去掉, 最后p+1 到 r+1的贡献就是 f_{r+1}-f_{p}


P5290 [十二省联考2019]春节十二响 [ 堆 + 启发式合并 ]

首先考虑链的情况, 从左边选一个最大的出来, 右边选一个最大的出来, 然后把两个都删掉, 答案加上更大者

推广到树上, 每一个节点需要将所有的儿子合并起来, 将两个堆合并时

每次选出最大的点, 把对面的堆的最大的从它的堆中删除, 然后将它保留

这样一次一次打擂台, 剩到最后的就是必须要选的. 堆用启发式合并就可以了

P4332 [SHOI2014]三叉神经树 [LCT]

发现每次修改的是自底向上的连续区间

对修改有贡献的点要么是1, 1改成2对上面有贡献, 要么是2, 2改成1对上面有贡献

于是我们LCT直接维护最深的不为1/2的点, 每次修改将它Splay, 然后对右子树整体修改(区间+1/-1)就可以了


P2173 [ZJOI2012]网络 [LCT]

建 c 棵LCT模拟就可以了


P5305 [GXOI/GZOI2019]旧词 [LCT]

先考虑k=1的情况, 我们先将询问离线, 然后把每个<=x的i到根的路径加1

查询时答案就是y到根的所有值的和

k=2时, 我们只需要将dep=1的点+1, dep=2的点+3, dep=3的点+5

于是就有 dep=1的点 + 1^k - 0^k, dep=2 的点 + 2^k - 1^k ...

我们预处理每个点要加多少, 然后LCT维护每个点加的次数


P3265 [JLOI2015]装备购买 [线性基 + 高斯消元]

一个量可以用其它的多个量表示, 就可以用线性基

具体跟处理异或的线性基差不多

如果当前位不为0, 就把它插入线性基, 然后将它后面的所有量的当前位都消成0

如果一个量全部是0了, 那么它就可以被之前的表示出来, 只好不要它


P5292 [HNOI2019]校园旅行 [ Spfa ]

我们可以插入二元组(x, y), x 到 y可以是回文串, 每次遍历x, y对面的两个节点(x1, y1)

如果两条边的权值相等, 那么x1 到 y1也可以是回文串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值