2019.12.14【NOIP提高组】模拟A 组总结

估分:100+40+5=145

实际:20+0+15=35

为何差距这么大?

T1 4815. 【NOIP2016提高A组五校联考4】ksum

题意:给你一个序列,让你求前大的子区间和。

很容易考虑到第一大的是[1,n],那么考虑第二大的是什么,一定是[1,n-1]和[2,n]中的一个。

因此,我们可以用堆维护区间,每次将堆顶弹出,再放入两个短1的两个小区间,再用哈希判一下重就好了。

这个是我考场的做法,但是我哈希打错了而丢了80分,这真是不应该。

其实还可以直接将所有[i,n]加进堆中,减的时候每次只用将对顶的右端点-1即可。

不论怎样堆中的元素个数一定是O(n)的。

时间复杂度O(k log n)。

T2:

题意:给你一棵树,每个点可以选[1,m]的其中一个值,让你求相邻两个节点相差值大于等于k的方案数。

对于 40%的数据:暴力dp。

设f[ i ][ j ]表示i号节点选j这个数的方案。f[x][i]=\sum f[son][j] ~~(~1<=i<=m~and~ ~|i-j|>=k~) 

你会发现 i 可取的值是连续的一段,所以 维护一个前缀和就可以不用枚举 i,时间复杂度O(nm)。

而考场时因为模的时候没有加上模数而导致溢出,所以又少了40分。

100%:

可以发现Dp 值间有一段的值是相同的。

所以我只需关心有两端有多少个与中间一段的 dp 值。

易得树的最大深度是 n-1=99,又因为 k<=100,所以 dp 值一端最多 只有 99*100 个不同的,接下来就是一段相同的数。 所以我只需设状态 dp[x][y]表示 x 节点的数是 y,且 x 的子树满足 条件的方案数。要求 y<=(n-1)*k。 中间的一段我只要算一个即可。 时间复杂度 ( n^2k)。

T3:4817. 【NOIP2016提高A组五校联考4】square

题意:让你求若干个给定区间中所包含的最大子正方形的边长。

考场打了个暴力15分。

正解是二维RMQ。

我们可以设f[i][j]表示以(i,j)为右下角的最大的矩形边长。

则f[i][j]=0(if a[i][j]==0 ) min( f [ i-1 ][ j ],f [ i ][ j-1 ],f [ i-1 ][ j-1 ] )+1 (if a[i][j]==1 )

然后设g[ k ][ l ][ i ][ j ]表示从(i,j)这个点往下连续的2^k行连续2^l列中f[ i ][ j ]的最大值。

那么对于每个给定区间,只需二分答案,再用二维RMQ,O(1)判断答案是否可行即可。

时间复杂度O(T log)。

常数优化技巧: 设状态要设 g[k][l][i][j],如果是[i][j]在前面,预处理时间会更长。 因为前一种设法,预处理时访问的内存位置更接近。

总结:
一定要检查。

要模的地方一定要反复模,减的时候要加模数,但是不能模太多导致超时了。

发布了199 篇原创文章 · 获赞 201 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zsjzliziyang/article/details/103604552