24.07 做题记录

24.7 降维技巧

约定

diff=1 大水题 黄以下 一眼切

diff=2 easy 下位绿及黄 能切

diff=3 medium 特殊的黄;绿;较简单的蓝 可能需要题解提供一步

diff=4 hard 蓝色+ 需要题解

diff=5 不可做题 紫色+ 做不了

前缀和/差分

P1115 最大子段和

diff:1

前缀和板子。

code

P3406 海底高铁

diff:1

注意读题。前缀和板子。

看好数据范围

code

P2671 [NOIP2015 普及组] 求和

diff:2.5 tag:前缀和 性质

难点在于读题。

(x,y,z) 表示的 编号。如果读对了题会发现 y 没用。

2y=x+z 可以发现 x,z 奇偶性相同。将奇偶不同的编号分开排序。

按照颜色第一关键字,大小第二关键字排序并前缀和即可。

"写的是题解的三倍,还多一支 log,附赠一堆细节"

code

P1314 [NOIP2011 提高组] 聪明的质监员

tag:二分 前缀和

你说得对,但是当答案可能超过 int 时最小值初始化应为 LONG_LONG_MAX 而不是 INT_MAX。

二分 W 对于每个不同的 W 处理一次 wiW 的前缀和,复杂度就是对的了。

注意二分返回 true/false 的条件,当 s>ans 时 返回 false

code

P1083 [NOIP2012 提高组] 借教室

我会线段树。

题意即为 (+,min) 线段树。

注意线段树的 add 函数改没改

code

P2367 语文成绩

差分板子。

code

P2882 [USACO07MAR] Face The Right Way G

diff:3 tag:贪心 细节

为什么从前往后看到方向朝后的就转回去是对的?

我们注意到把一个点转两次等于啥也没干 可以模拟得出贪心正确性。

优化简单于贪心。xor 差分维护当前是否转向即可。

注意代码细节,差分的下一个数是 j+i 没有 +1!

code

高维前缀和/差分

P2004 领地选择

diff:1

板子题。但是写对板子。

sumi,j=sumi,j1+sumi1,jsumi1,j1+ai,jsumx2,y2sumx11,y2sumx2,y11+sumx11,y11

code

P3397 地毯

diff:1

板子。

code

P2280 [HNOI2003] 激光炸弹

diff:1.5

坐标有0 坐标有0 坐标有0 坐标有0。记得对所有的数组偏移 1,不然 91 pts。

code

P1719 最大加权矩形

diff:1

板子。建议你谷课程题单减少板子题数量。

code

P3017 [USACO11MAR]Brownie Slicing G

diff:3.5 tag:贪心 性质 二分 前缀和

USACO 首先考虑贪心

二分答案,对于每一次 check,我们可以贪心。

具体的,先满足列的条件。如果该列在满足 x 情况下无法 b 块,那么加一行,注意每一块的范围是以 (上次分割行,上次分割列) 和 (枚举点行,枚举点列) 形成的长方形而不是一行连着取。是否满足条件即是否 a

前缀和即可。

因为少写 else 多交两发。

code

[ARC100E] Or Plus Max

diff:4 tag:sosdp 高维前缀和

牛逼题。参考链接1 参考链接2

考虑对每个 k 分开计算,即令 Ak=maxiorj=kai+aj,则 ansk=maxi=1kAi又注意到上式即 Ak=maxi,jai+aj,ansk=maxi=1kAi 这是由于或运算的不减性。该转化是进行 sosdp 的前提。

事实上该问题可以枚举子集,O(3n),事实上我们可以非容斥计算前缀和。

e.g. 三维前缀和

for(int i = 1; i <= n; i++)
    for(int j = 1; j <= n; j++)
        for(int k = 1; k <= n; k++) 
            a[i][j][k] += a[i - 1][j][k];
for(int i = 1; i <= n; i++)
    for(int j = 1; j <= n; j++)
        for(int k = 1; k <= n; k++)
            a[i][j][k] += a[i][j - 1][k];
for(int i = 1; i <= n; i++)
    for(int j = 1; j <= n; j++)
        for(int k = 1; k <= n; k++)
            a[i][j][k] += a[i][j][k - 1];

sosdp 是一个每一维度长度都为 2 的高维 dp。

for(int i=0;i<=n-1;i++)
    for(int j=0;j<=(1<<n)-1;j++)
        if((1<<i)&j)
            m[j]=m[j]+m[j-(1<<i)];

这段代码中 jj2i 的上一层,从 0 开始,建议背过

从 dp 角度理解:

定义 fi,r 表示当前处理到二进制最后 i 位,状态为 r 的情况,当枚举 i+1 位时,若 r 即当前状态为 1,就从 fi,r,fi,r2i 转移,分别表示有/无该位的情况并合并,否则从 fi,r 转移即可。实现上,我们滚动掉第一维。

求超集仅需在 if 中加入一个 ! 取反即可。

code

树上差分

P3128 [USACO15DEC] Max Flow P

diff:2

我会树剖。

code

P3258 [JLOI2014] 松鼠的新家

diff:2

我也会树剖。

code

P2680 [NOIP2015 提高组] 运输计划(todo)

todo

P1600 [NOIP2016 提高组] 天天爱跑步(todo)

todo

离散化

P1097 [NOIP2007 提高组] 统计数字

diff:1

板子。

code

P1955 [NOI2015] 程序自动分析

diff:2.5 tag:并查集 离散化

diff=2.5 而不是 2 的原因是写挂了若干发。

我们只需要判断是否在不相等时能否满足,原因是显然的——等式具有传递性,所以我们事实上只需要维护相等这一个并查集即可。

离散化写了要用。并查集要写 f[i]=i

fun fact:洛谷 #2 #10 放反了,所以你如果没有离散化会 RE #2

code

P1052 [NOIP2005 提高组] 过河

diff:3 tag:dp 离散化

细节题。

显然可以进行 dp。有转移式子:

fi=minfi,fij+[pi=1]

其中 pi 表示是否该位置有石子。

由于 1L109,并且答案与跳的石子数量无关,我们需要且必须进行离散化,由于我不想做数学题,所以我们不卡离散化常数,lcm1,2,10=5040,所以如果两个石子的距离超过 5040,我们直接将距离 5040 即可。

细节的原因是跳到或跳过 L 时都可以产生贡献,注意统计答案。

题目不保证输入的 M 有序,否则可以拿到 8 pts 的好成绩。

code

双指针

P1102 A-B 数对

diff:1

你谷题单能不能少点__。

code

P3143 [USACO16OPEN] Diamond Collector S

diff:2 tag:双指针 贪心

我们双指针枚举分界线左边的贡献,具体的,每次超过 k 时,左指针右移,否则右指针右移;右边的贡献直接取分界线到最后的后缀 max 即可。

注意边界值的处理,挂了 3 发。

code

P4653 [CEOI2017] Sure Bet

diff:3 tag:贪心 双指针

三分神秘看不懂。考虑贪心。

显然要从价值高的往价值低的拿,当一组的收益小于另一组时,继续拿另一组显然对于答案是不优的,所以贪心策略即为排序后,拿收益较小的一组的最大值。

不是啥传统意义上的尺取法双指针。

注意可以不取,否则会 97 pts。细节。

code

P1311 [NOIP2011 提高组] 选择客栈

diff:2.5 tag:贪心

注意做题之前要读题。注意做题之前要读题。注意做题之前要读题。注意做题之前要读题。注意做题之前要读题。

考虑一个桶,表示在第 i 个元素前的相同颜色元素个数,如果当前位置的元素 <p 我们再对这个桶计入上一个 <p 的位置到该处这段位置的元素,并将当前元素的颜色所属的桶的大小计入贡献,否则,仅将当前元素所属的桶的原大小计入贡献。

为什么这么做是对的,因为不要求两个人住的地方的颜色是连在一起的,所以只需要看两个人所处的位置,不需要考虑其他因素。所以注意读题。

code

P1638 逛画展

diff:2

尺取法板子,但是我不会。

先推右指针,记录区间内每种颜色出现次数,满足条件的情况下推左指针,一直到有一种颜色出现次数为 0 时,推右指针。以此继续即可。

代码卡了一天。

for(;j<=i;j++)
{
	t[a[j]]--;
	if(t[a[j]]==0)
	{
		cnt--;
		if(i-j+1<minn)
		{
			minn=i-j+1;
			aa=j,bb=i;
		}
		j++;
		break;
	}
}

注意两个细节:break 的位置和 j++

特别的,如果写双指针不建议写成 for 循环的形式,因为指针变量的自增很有可能在 break 时少触发一次导致错误,且这个很难调。

code

UVA11572 唯一的雪花 Unique Snowflakes

diff:1.5

尺取法板子,和上一题差不多,如果合法右移右端点,否则右移左端点。

没有代码。因为上不去 UVA。

[ABC098D] Xor Sum 2

diff:2.5 tag:xor

典中典 xor 性质题,由于异或是不增的,所以 i=lrai=xori=lraiiai+ai+1=aixorai+1 也就是这任意两数二进制位不能有同为 1 的情况。

也就是异或是不进位二进制加法

写个前缀异或和然后跑双指针即可,注意 ans 的贡献到底两头是取不取,别挂细节。

code

P1083 [NOIP2012 提高组] 借教室

diff:1

我会线段树。空间开足了记着。

code

CF939E Maximize!

diff:2.5 tag:贪心

性质题。

由于给定的数是递增的,所以新数一定要放入。

小于集合平均数的数放入一定更优。

尺取法维护小于集合平均数的数即可。

code

单调栈

P2866 [USACO06NOV] Bad Hair Day S

diff:2

单调栈板子,但是我也不会。

维护一个单调上升的栈,栈内的奶牛均可以看到最新入栈的奶牛。每次对答案贡献统计栈内的元素数量即可。

不开 long long ___。

code

P3467 [POI2008] PLA-Postering

diff:3

主要是谜语人题面。覆盖的意思是想象你面前横着有一排建筑要把面向你那个面覆盖而不是其它的。

如果两个建筑高度不同,无论如何都要用两张,可以少用一张海报当且仅当两个建筑高度相同且中间的高于它。

由此,可以维护一个单调严格递增栈,加入元素时如果最后出栈的元素等于当前元素,ansans1

code

P1950 长方形(todo)

todo

单调队列

P1886 滑动窗口 / P2032 扫描 / P2251 质量检测 / P1440 求m区间内的最小值

diff:1.5

单调队列板子,使用 deque 实现。

怎么这么多板子。

P1886 P2032 P2251 P1440

P2880 [USACO07JAN] Balanced Lineup G / P1816 忠诚

diff:1

ST 表板子。

P2880 P1816

P2216 [HAOI2007] 理想的正方形 (todo)

diff:3

二维 ST 表/单调队列板子。

没写。

P1714 切蛋糕

diff:2

单调队列优化 dp 板子,远古时期写的题。

具体的这题需要先前缀和再上板子。

code

P1725 琪露诺

diff:2.5

多了 0.5 是因为写炸了若干发,被琪露诺附身了(悲)

fi=maxiRjiLfj+ai

使用了题解区没人用的坐标偏移,注意偏移要偏移全了。

挂 hack 的原因是要将初值赋值为负无穷,分清下标和值

code

P2627 [USACO11OPEN] Mowing the Lawn G

diff:2

也是远古写的题了,好像也是维护个前缀和再上板子的类似状物。

code

P2034 选择数字

diff:3

正难则反!

不妨把问题转化成在 k 个数内选一个使得和最小。

写坐标偏移很多细节所以不要写。较好的写法是每次更新循环到的那个位置,队列的出队条件是 ik

code

P3800 Power收集

diff:2.5

由于坐标偏移的写法细节太多,所以写的时候一度 code diff >3 的。

其实就是跑 n 轮单调队列。

写挂点:小心负数下标;不要使用坐标偏移;在原数组上 dp(f[x][y]=v);第二次循环仍从 j 开始;先出入队再算贡献。

code

posted @   ChthollyNS  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示