【题解】替换/子数组

首先是本次测试总结:

T2是练习的原题,这道题我刚好练习时没做,太巧了。

T3我很快看出来从小到大排序就是答案(逆序对为0),后来暴力不过,于是从选第N+1条裤子递推到了选第一条裤子,再重新输出。不过用一个数组记录后面裤子的前缀,一个数组记录前面裤子的前缀(不论选哪条裤子都适用),就很简单了。这就是记忆化思想,包括昨天的题。(我最后半小时才想到一个复杂的方法,太惊险。)

T4是二分+贪心,由MID来决定I的选择,判定答案往往能贪心,因为它只关注的是MID能否成立,更好操作。就像知道了已知条件,比直接求解问题更简单。

继续努力,向大佬们看齐OR2!


A. 替换

对于一个大于1的整数X,,你可以进行以下替换操作:

删掉它,把它换成三个数:[X/2],[X%2],[X/2]。

现在给你一个数列,开始数列只有一个整数N,你每次可以在数列中选择一个大于1的整数进行上述操作,直到这个数列最后全是1或0为止。

接下来,在最后的数列中查询区间[L,R]中有多少个1。输出1的个数。


解析:我们发现对于一个数N,会被拆分成两部分,这两部分是对称的。但难点在于它只告诉我们求最终序列所给区间的1,似乎必须把整个数组递归模拟下来才行。而且1似乎也没什么特点,可以是每次中间余的数,也可以是最终拆分成的数。

所以我们必须从最终序列入手,再缩小规模,直至操作结束。

再往下分析,我们可以求出最终序列长len:

len=1; for(ll i=n>>1;i;i>>=1) { len=len*2+1; }

定义函数s(len,l,r,x)表示在数x所形成序列中L~R区间1的个数,len表示序列长度。由于最终序列左右一定具有对称性,我们可以根据l,r的位置把序列分割成左右两块,在更小的序列中分别求值,再累加返回。

没错,这就是:分治!

尽管这个区间横跨左右部分,仍可以强行分成两部分解决。

ll flag=0,t=len/2+1; if(n==1) return 1; if(n==0||l>r) return 0; if(l<=t&&r>=t&&n%2==1) flag=1; return search(len/2,l,t-1,n/2)+search(len/2,1,r-t,n/2)+flag;

【标签】分治


B. 子数组

给出一个N行N列的二维数组,元素只取0,1,2这三种值,并且每行、每列的元素值单调不下降。在此数组中,找出一个值全部等于0或者全部等于2的子二维数组,使得这个子数组的元素个数最多。子二维数组是指行数、列数不超过N的连续的一个矩形区域。

样例输入
8
4 0
4 8
4 8
3 7
3 6
3 5
2 3
0 2

样例输出
12
4

样例说明
输入数据描述的二维数组是这样的:
0 0 0 1 1 1 1 1
0 0 0 1 1 1 1 2
0 0 0 1 1 1 1 2
0 0 1 1 1 1 2 2
0 0 1 1 1 2 2 2
0 0 1 1 2 2 2 2
0 1 2 2 2 2 2 2
0 2 2 2 2 2 2 2
可以看出,一共有4个值全部相同的子二维数组,分别是:(1,1)到(6,2);(5,6)到(8,8); (7,3) 到 (8,8); (6,5)到(8,8).

解析:既然这道题是求0和2的最大矩形,你就明白了。0和2显然比1规则,根据输入处理每行的0,2个数,再找个最大矩阵就好了,因为一边是对齐的,所以很好操作

引入:单调栈(不用也行)

大致思想是:1~n每次进入一行0(以0举例),设栈s[],如果个数大于栈顶,直接进栈;否则不断取出栈顶,直至栈为空或者栈顶矩形高度比当前小,我们累计被弹出矩形宽度之和,借此更新答案,结束后,把一个高度为当前矩阵·宽度为累加值的新矩形入栈。

//当前内容引自算法竞赛 for(int i=1;i<=n;i++) { if(a[i]>s[p]) { s[++p]=a[i],w[p]=1; } else { int width=0; while(s[p]>a[i]) { width+=w[p]; ans=max(ans,(long long)width*s[p]); p--; } s[++p]=a[i],w[p]=width+1; } }

这只是一种思想,只会打是没有用的。如(s[p] > a[ i ]),不一定要严格大于,若有高度相同的矩阵,也应该弹出,还有边界设定,都很讲究。

(完)

好累啊,点个赞呗


__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530437.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(15)  评论(0编辑  收藏  举报  
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示