一次TLE的教训

一次TLE的教训

在CF上刷题的时候,遇到一道数据很大的题。

https://codeforces.com/edu/course/2/lesson/2/3/practice/contest/269118/problem/B

n可以取到3e5,我用O(N*log(N))完全能过的,但是…

在这里插入图片描述

我不理解,刚开始我以为是有个特例让我二分死循环了,然后我对拍了无数次,跑的都挺快的,我试着限制二分次数break掉,还是TLE,这说明是程序复杂了。尝试了很多种办法,比如记忆化,更快的快读,不开long long等…

后来在讨论里看到也有人TLE了,下面有人评论说,比较的compare函数要自己写,这时我突然想到,在二分里如果check不是O(1)的话,复杂度确实会非常可怕,我试着自己写了个compare,但还是TLE,不过它提供了一个思路,那就是减少大循环里的一些很复杂的函数,比如strlen,size(),等,它们其实都是O(N)的。

我在循环里去掉它们,并写到循环的外面之后,时间确实节省了不少,因此就AC了。

在这里插入图片描述

其实compare只能节省一点点的时间,毕竟都是O(N)的.

继续按照这样的思路优化,我把函数的形式参数都去掉,都放到全局区,提交上去之后,我大受震惊。

在这里插入图片描述

这也太快了吧,函数参数以值传递确实会有开销,但我没想到影响这么大。。。

我又试了一次传引用,突然就真相大白了,时间也是非常的短。

string好歹也是c++里的一个类,作为参数传递的时候调用构造函数赋值过去,函数结束之后又会调用析构函数,确实开销很大。

所以,对于数据大的题目如果TLE,如果算法本身没问题,试着这样去优化:

循环里少放strlen,size() 等复杂度大的函数,在不修改对象的情况下,函数参数尽量传的是引用(其实指针也行)。

还有一些经验性的结论:数据没爆的话关掉long long可能就过了。一般关了同步的cin是够用的而不必快读(除非那种黑题)。换个编译器可能就过了,比如poj上的g++TLE了,改用C++就能过。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值