题外话:这题做了我好久。。不过也同时把动态和静态的线段树写了一两次。。练了手。。过段时间看完区间加法回来学写二维的, mark soj 1045
思路:一看到RMQ问题心情澎湃激动就想着sparce table能不能套~~算计了一下。。发现ST算法此处貌似不可行。。也就是说我必须去学线段树(interval tree)。。于是看了一些简陋的资料理解了之后就开始写了。。先写了个动态指针的。。很果断MLE了。。于是迅速改静态用数组的,结果持续tle。。
我原来是now.max=MAX{now.lmax, leftson.max,leftson.rmax+rightson.lmax,rightson.max,now.rmax}
lmax为当前区间从最左端往右开始可以取到的最大值,rmax则是从右往左。max就是当前区间最大值,就是所求了。
tle后苦苦思索发现now.lmax & now.rmax是多余的,也就是说now.max=MAX{leftson.max,leftson.rmax+rightson.lmax,rightson.max}即可。。
(P.S. 其实此处你只要从左往右比较就不需考虑那个同最大值取i,j最小的问题,但是计算lmax,rmax比较的时候还是要注意一下等号)
但依然苦闷的TLE。。。经过我苦苦的各种compare后。。发现iostream的cin和cout一改成stdio的格式化输入输出就ac了。。。。
反思:此处引用豆腐师兄的经验:
第一、iostream的结构太复杂
第二、c中的函数直接,c++中输入输出流很庞大,加了很多中间开销
第三、scanf,printf 是带缓冲的 cin,cout 是不带缓冲的,
所以处理大数据量读入时,scanf,printf调用io次数少,所以速度快
第四、其实这样说你好理解一点,cout 和cin 在运行是要先进入栈,然后在出来,所以就会慢一点嘛!
就好像cout < <a < <a++;如果,a的初值是5,那么运行结果就是 4 5.
这就是因为 a++先进入栈,a再进入,然后从栈第计算,先a++,再a 这时第2个a就是4了,再从栈顶输出,就是4,5 了,这样的步骤就使得 cout慢一点咯(深刻点)
第五、c++是面向对象的,由于涉及到类,所以慢,我曾经看过一本书,是关于C++优化的,里面谈到了这个问题,书里举了个简单的例子:100万次的迭加
C++使用了一个最最简单的类,结果比C的代码慢了好象10-20倍的样子(具体数字我记不太清楚了),结果非常的惊人!