0%

思路讲解

终于是看懂题目是什么意思了。其实就是问你这张生成网格中的0的联通块最多包含多少个0。

image

比如这张图中是包含9个。

那么唯一的问题就是,这张生成网格太大了,最多可能有4e10个块。这就有点恐怖了。

如果说跑dfs,bfs,O(n2)O(n^2) 无法通过此题。

唉,其实像这种题反而难想,因为暴力太容易想到,但是暴力的优化就不是很容易了,可能要另起炉灶了。

那么就直接使用dp的类似思路,一列一列的推过去,然后就做出来了?一次AC!

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

一般难度,看着比较唬人。

其实就是看看有多少个需要替换位置,需要将其替换为比k小或者大的数。

那其实我们只要知道有几个替换位置就行。因为这个替换无视距离,不要求连续。(读题不要读成以为是连续的了)
然后注意大的数和小的数是可以对冲的,能内部解决就内部解决,否则会WA testcase2 的第3104个点。

1
2
// 	这些数肯定要换,但可以内部对冲的,就内部对冲,不能内部对冲的,就找外援(max-min)
cout<<needRep+needRep_+(max(needRep_,needRep)-min(needRep,needRep_))<<" ";

AC代码

心路历程(WA,TLE,MLE……)

写成这样

1
2
l_=idx+1;
idx=(l_+r_)/2;

而不是这样

1
2
idx=(idx+1+r_)/2;
l_=idx+1;

(l_的idx已经不是原来的idx了)

这种idx最好还是用固定式子得出

思路讲解

preA配合sufA,寻找最优插值位置

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

其实也是自己琢磨琢磨出来的,当然不好好写复盘大抵是看不懂以前自己的思路的。

1
2
3
4
5
FOR(i,0,N-1){
diff[i]=B[i]-A[i];
}
ll ans=1;
// diff是负值表示需要调和

就是直接模拟肯定TLE,但是可以退而求其次,**一个一个模拟。**在这个需调和块遇到其他的需调和块之前,不用担心操作有后效性。在碰到其他调和块之后,让他先开路,如果他变成0了,再变成你了。

当然可能碰到多个调和块,这个时候就是使用栈来维护,一个为0弹出1个,换后面一个,直到处理完这个最初的,弹出。

AC代码

https://codeforces.com/contest/2089/submission/316959785

心路历程(WA,TLE,MLE……)

这段代码会造成这个死循环,虽然说比较隐蔽,但这个死循环的罪魁祸首就是upLab。

这个upLab和lab如果相同的会导致lab=upLab 这句话出现问题,并不起到作用。

这个代码过了5个点,但还是有点问题,怀疑是因为我这个算法没有去真实的记录每个点的实际抵消所需操作数,现在看起来要改一改了,确保这个每个点的抵消所需操作数都被真实记录。

但好像也不太对,就是我们都是把这个碰到的 diff<0diff<0 的点搞到 0≥0 才罢休,而且这个也会记录到最初的点当中

https://codeforces.com/contest/2089/submission/316947463

事实证明我的猜想是对的,只是ltot这个东西就有问题,直接改成栈,把这个ltot优化掉了就好了

思路讲解

其实想明白了就很简单,就是这个就是平均数(向上取整),那么就找离平均数最近的素数就行,然后让这个数列的上界平均数不断是这个素数就行。

AC代码

心路历程(WA,TLE,MLE……)

https://codeforces.com/contest/2090/submission/316398539

其实还可以,过了8个点,但是在面对大数的情况时力不从心。