HDU 6638 Snowy Smile

离散后用线段树维护最大子段和

枚举上界遍历下界更新答案

时间复杂度O(n^2logn)


代码: 

/*
    Zeolim - An AC a day keeps the bug away
*/
 
//pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
 
#define mp(x, y) make_pair(x, y)
#define fr(x, z, y) for(int x = z; x < y; ++x)
 
typedef long long ll;
typedef double ld;
typedef std::pair<int, int> pii;
typedef std::vector <short> vi;
//typedef __int128 ill;
 
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 1e18;
const ll MOD = 1e9 + 7;
const int MAXN = 1e6 + 100;
 
ll n, m;
 
struct node
{
	ll l, r;
	ll val;
	ll sum, lmax, rmax;
}tr[MAXN * 4];
 
void push(node &now, node &ls, node &rs)
{
	now.sum = ls.sum + rs.sum;
	now.lmax = max(ls.lmax, ls.sum + rs.lmax);
	now.rmax = max(rs.rmax, rs.sum + ls.rmax);
	now.val = max(ls.val, max( rs.val, ls.rmax + rs.lmax) );
}
 
void build(ll now, ll l, ll r)
{
	tr[now].l = l, tr[now].r = r;
	ll mid = (l + r) / 2;
	if(l == r) {tr[now].val = tr[now].sum = tr[now].lmax = tr[now].rmax = 0; return;}
	build(now * 2, l, mid);
	build(now * 2 + 1, mid + 1, r);
	push(tr[now], tr[now * 2], tr[now * 2 + 1]);
}
 
void change(ll now, ll p, ll v)
{
	if(tr[now].l == tr[now].r) { tr[now].val = tr[now].sum = tr[now].lmax = tr[now].rmax = (tr[now].val + v); return;}
	ll mid = (tr[now].l + tr[now].r) / 2;
	if(p <= mid) change(now * 2, p, v);
	if(p > mid) change(now * 2 + 1, p, v);
	push(tr[now], tr[now * 2], tr[now * 2 + 1]);
}
 
node ask(ll now, ll l, ll r)
{
	if(l <= tr[now].l && r >= tr[now].r) return tr[now];
	ll mid = (tr[now].l + tr[now].r) / 2;
	if(r <= mid) return ask(now * 2, l, r);
	if(l > mid) return ask(now * 2 + 1, l, r);
	node ls = ask(now * 2, l, r), rs = ask(now * 2 + 1, l, r), ans;
	push(ans, ls, rs);
	return ans;
}
 
struct rec
{
	ll x, y, val;
}R[MAXN], arr[MAXN];

bool cmp(rec a, rec b)
{
	return a.x < b.x;
}

ll vx[MAXN] = {0}, xf = 0;
ll vy[MAXN] = {0}, yf = 0;

ll retx(ll x) { return lower_bound(vx, vx + xf, x) - vx + 1; }
ll rety(ll x) { return lower_bound(vy, vy + yf, x) - vy + 1; }

signed main()
{  
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    //freopen("d:out.txt","w",stdout);
  	//freopen("d:in.txt","r",stdin);
  	ll t;
  	cin >> t;
  	while(t--)
  	{
  		xf = yf = 0;
  		cin >> n;
	  	fr(i, 0, n)
	  	{
	  		cin >> R[i].x >> R[i].y >> R[i].val;
	  		vx[xf++] = R[i].x;
	  		vy[yf++] = R[i].y; 
	  	}
		
		sort(vx, vx + xf);
	  	xf = unique(vx, vx + xf) - vx;
	  	sort(vy, vy + yf);
	  	yf = unique(vy, vy + yf) - vy;
	
	  	fr(i, 0, n)
	  	{
	  		arr[i + 1].x = retx(R[i].x);
	  		arr[i + 1].y = rety(R[i].y);
	  		arr[i + 1].val = R[i].val;
	  	}
	  	
	  	sort(arr + 1, arr + n + 1, cmp);

	  	ll ans = 0;

	  	for(ll i = 1; i <= n; ++i)
	  	{
	  		if(arr[i].x != arr[i - 1].x)
	  		{
	  			build(1, 1, yf);
	  			for(int j = i; j <= n; ++j)
	  			{
	  				if(j != i && arr[j].x != arr[j - 1].x)
	  					ans = max(ans, tr[1].val);
	  					
	  				change(1, arr[j].y, arr[j].val);
	  			}
	  			ans = max(ans, tr[1].val);
			}
	  	}

	  	cout << ans << '
';
	  	
  	}
  	
    return 0;
}
/*
2
4
1 1 50
2 1 50
1 2 50
2 2 -500
2
-1 1 5
-1 1 1
*/
/*
1
2
-1 1 5
-1 1 1*/
原文地址:https://www.cnblogs.com/zeolim/p/12270350.html