提高模考7.30 T4《柱状图》题解

蒟蒻实在太菜,只能提供一种 非正解 的简单做法,通俗易懂,不用晦涩难懂的数学公式

巨佬的线段树维护凸包我不会,那就只好上随机化了

一看这道题目要求最值,那就是非常明显的st表了

相信大家都会吧

不会的先干了P3865

st表是很好维护的:

void init(){
	for(int i=1;i<=n;++i) stx[i][0]=a[i].x,sty[i][0]=a[i].y;
	for(int j=1,t=1;j<=23;++j,t*=2){
		for(int i=1;i<=n-2*t+1;++i){
			stx[i][j]=min(stx[i][j-1],stx[i+t][j-1]);
			sty[i][j]=min(sty[i][j-1],sty[i+t][j-1]);
		}
	}
}

也是非常容易查询的:

int queryx(int l,int r){
	int lg=log2(r-l+1);
	return min(stx[l][lg],stx[r-(1<<lg)+1][lg]);
}
int queryy(int l,int r){
	int lg=log2(r-l+1);
	return min(sty[l][lg],sty[r-(1<<lg)+1][lg]);
}

但是当有一组数据为 1-n 的升序排列时,时间复杂度接近 n^2 ,快乐拿下 TLE 20

于是随机化就有了

用系统函数 random_shuffle(p.begin(),p.end())就可以让p数组重新随机排列,这样就不用担心 TLE 了 基本卡不掉,充分发扬人类智慧

代码如下:

for(int i=1;i<=n;++i) p.push_back(i);
	random_shuffle(p.begin(),p.end());//随机化,防止被卡 

但是如果这样,提交上去还是会拿到光荣的 TLE 20

蒟蒻思考良久,终于在统计答案的时候发现了一个有点玄学的优化

原来的统计是这样的:

for(int i : p){
  for(int j=i;j<=n;++j){
    int cnt=queryx(i,j)*queryy(i,j);
    ans=max(ans,(j-i+1)*cnt);
  }
}

我们发现,在统计完现在的 i-j 区间后,会有一些区间一定不比当前优,因为它们再大也不会比 ans 大

以下记 qx = queryx(i , j) , qy = queryy(i , j) , q = qx \times qy

现在我们枚举到了 (i , j) ,期望找到下一个枚举到的 j' > j 使 ans' = (j' - i + 1) \times q' > ans

以下记 j - i + 1 = len , j' - i + 1 = len'

非常显然,由于我们预处理st表是求 min ,那么容易发现, q \ge q'

那就意味我们可以构造一个不等式:

len' \times q' \ge ans

\therefore len' \times q \ge ans

\therefore len' \ge \frac{ans}{q}

\therefore j' \ge \frac{ans}{q} + i - 1

于是我们的最优化数学剪枝就做完了

代码如下:

for(int i : p){
  for(int j=i;j<=n;++j){
    int cnt=queryx(i,j)*queryy(i,j);
    ans=max(ans,(j-i+1)*cnt);
    j=(ans/cnt)+i-1;//最优化数学剪枝
  }
}

完结撒花!!!

最后说一句:random_shuffle() ,只支持C++17前的,后被弃用,变成了shuffle()函数

9 个赞

时间复杂度错误。

4 个赞

如果可以在随机的情况下期望次数 <<\mathcal{O}(n^2) 的话,那我承认我不对。

4 个赞

期望次数绝对不满 n^2
大约 n log n

4 个赞

证明下

3 个赞

这题分治加上线段树维护凸包总共是 \mathcal{O}(n\log^2 n) ,合着就是您爆标了呗。

3 个赞

他的ST 表甚至是用线段树写的/cf

3 个赞

时间复杂度不对的做法 可以这样反馈,但不应该如此 不知廉耻 地反驳那些想卡你假做法的人。

4 个赞

哪怕这篇题解可以被卡掉,但是他仍然是一种可以取得高分的策略。而且注意到你很难卡这个代码,如果他用 shuffle 随机枚举 i 那你怎么卡?

如果可以卡掉的话你给一组,有说服力,我们心悦诚服,对吧?

4 个赞

主要是说随机题解很难卡,你其实没有必要为了这个吵起来

4 个赞

你去考场上写随机化,期望得分 [0,100] 直接给你挂零分/xk

4 个赞

首先, 随机化这种作法本来就是一种较为玄学的做法, 如果rp不高可能就会挂掉, 且jyp同学只是提供一种思路, 没必要为此争吵

4 个赞

我见到假做法我表达一下想要卡的意愿没有问题吧。

他要是不说话啥事没有。

3 个赞

你有想卡的意愿是可以,但请先大概有个思路,以便大家能够更好的讨论问题

3 个赞

先经典结论一下再根号平衡一下再后缀数组一下再失配树一下再树状数组一下就好了

3 个赞

@lzyqwq 你倒不如说是A+B一下再贺题解一下

4 个赞

https://www.luogu.com.cn/article/y664stg9

不要乱说别人贺题解。这题第一篇题解是我的。

3 个赞

事实上你们可以看一下这道题的高分代码,都有谁是正经地写线段树维护凸包,我看了五六个,全部都是随机化,我认为楼主写一下解释一下没什么问题呀?怎么就吵起来了??? :roll_eyes:

4 个赞

你看的是哪个班的,提高模考是没有一个正常写的

3 个赞

我还是那句话,考场 OI 赛制除非你是纯纯低能没人写随机化的,CCF 完全有权利使你的代码挂到 0 分

3 个赞