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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章