UVa 1400
线段树区间合并,惟一不满意的就是做的拖的时间太长,并且写出来代码没有一边过的自信,能力是需要培养的,rush自己一把吧。
此外,一直WA的原因是越界的问题,这种考察数据范围后,每个Int需要注意替换成Long Long
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <cassert>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
#include <unordered_map>
using namespace std;
typedef long long LL;
const LL INF= 1LL<<60;
const int maxn= 500000+5;
inline LL GetS(int l, int r);
struct Seg
{
int l, r;
Seg(int ll= 0, int rr= 0) : l(ll), r(rr) {}
bool operator < (const Seg &rhs) const
{
LL lv= GetS(l, r), rv= GetS(rhs.l, rhs.r);
if (lv < rv){
return true;
} else if (lv == rv){
return l > rhs.l || (l == rhs.l && r > rhs.r);
} else{
return false;
}
}
};
struct Intv
{
Seg ipre, isur, isub;
Intv(Seg pre= Seg(), Seg sur= Seg(), Seg sub= Seg())
: ipre(pre), isur(sur), isub(sub)
{}
};
int n, m;
LL psum[maxn];
Seg mpre[maxn<<2], msur[maxn<<2], msub[maxn<<2];
inline LL GetS(int l, int r)
{
return 0 == l ? -INF : psum[r]-psum[l-1];
}
inline void PushU(int x, int lo, int hi)
{
int lc= x<<1, rc= x<<1|1;
mpre[x]= max(mpre[lc], Seg(lo, mpre[rc].r));
msur[x]= max(msur[rc], Seg(msur[lc].l, hi));
msub[x]= max(msub[lc], msub[rc]);
msub[x]= max(msub[x], Seg(msur[lc].l, mpre[rc].r));
}
void Build(int x, int lo, int hi)
{
if (lo > hi){
return;
}
if (lo == hi){
msub[x]= msur[x]= mpre[x]= Seg(lo, hi);
return;
}
int mid= (lo+hi)>>1;
Build(x<<1, lo, mid);
Build(x<<1|1, mid+1, hi);
PushU(x, lo, hi);
}
Intv Query(int x, int lo, int hi, int L, int R)
{
if (lo > hi){
return Intv();
}
if (L <= lo && hi <= R){
return Intv(mpre[x], msur[x], msub[x]);
}
int mid= (lo+hi)>>1;
Intv lc, rc;
Intv ret;
bool lflag= false, rflag= false;
if (mid >= L){
lc= Query(x<<1, lo, mid, L, R);
lflag= true;
}
if (mid+1 <= R){
rc= Query(x<<1|1, mid+1, hi, L, R);
rflag= true;
}
if (lflag && rflag){
ret.ipre= max(Seg(max(lo, L), rc.ipre.r), lc.ipre);
ret.isur= max(Seg(lc.isur.l, min(hi, R)), rc.isur);
ret.isub= max(lc.isub, rc.isub);
ret.isub= max(ret.isub, Seg(lc.isur.l, rc.ipre.r));
} else{
ret= lflag ? lc : rc;
}
return ret;
}
int main(int argc, char const *argv[])
{
Intv ans;
int kase= 0;
while (2 == scanf("%d%d", &n, &m)){
psum[0]= 0;
for (int i= 1; i <= n; ++i){
scanf("%lld", psum+i);
psum[i]+= psum[i-1];
}
Build(1, 1, n);
printf("Case %d:\n", ++kase);
int s, e;
while (m--){
scanf("%d%d", &s, &e);
ans= Query(1, 1, n, s, e);
printf("%d %d\n", ans.isub.l, ans.isub.r);
}
}
return 0;
}