hdu6638 Snowy Smile (最大權值和矩陣、線段樹維護最大子段和)

 

#include <bits/stdc++.h>
#define ll long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int maxn = 1e5;
struct N{
	ll lm,rm,mm,sum;
}t[maxn<<2];
void push(int rt){
	t[rt].sum = t[ls].sum + t[rs].sum;
	t[rt].lm = max(t[ls].lm,t[ls].sum+t[rs].lm);
	t[rt].rm = max(t[rs].rm,t[rs].sum+t[ls].rm);
	t[rt].mm = max(max(t[ls].mm,t[rs].mm),t[ls].rm+t[rs].lm);
}
void build(int rt,int l,int r){
	t[rt].lm = t[rt].rm = t[rt].mm = t[rt].sum = 0;
	if(l==r)return ;
	int mid = l+r>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	push(rt);	
}
void update(int rt,int l,int r,int pos,ll val){
	if(l==r){
		t[rt].sum+=val;
		t[rt].lm = t[rt].rm = t[rt].mm = t[rt].sum;
		return;
	}
	int mid = l+r>>1;
	if(pos<=mid) update(ls,l,mid,pos,val);
	else update(rs,mid+1,r,pos,val);
	push(rt);
}
//以上求最大子段和
struct P{
	int x,y;
	ll val;
}p[maxn]; 
bool cmp(P a,P b){
	return a.y == b.y?a.x<b.x:a.y>b.y;
}
vector<int> vx,vy;
int getidx(int x){
	return lower_bound(vx.begin(),vx.end(),x) - vx.begin()+1;
}
int getidy(int y){
	return lower_bound(vy.begin(),vy.end(),y) - vy.begin()+1;
}
 
int main()
{
	int _,n,len;
	for(scanf("%d",&_);_;_--){
		vx.clear();	vy.clear();
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d %d %lld",&p[i].x,&p[i].y,&p[i].val);	
			vx.push_back(p[i].x);
			vy.push_back(p[i].y); 
		}
		sort(vx.begin(),vx.end());	vx.erase(unique(vx.begin(),vx.end()),vx.end());	len = vx.size();
		sort(vy.begin(),vy.end());	vy.erase(unique(vy.begin(),vy.end()),vy.end());
		for(int i=1;i<=n;i++){
			p[i].x = getidx(p[i].x);
			p[i].y = getidy(p[i].y); 
		}
		sort(p+1,p+n+1,cmp);
		ll ans = -1e18,last = -1;
		for(int i=1;i<=n;i++){//上邊界 
			if(p[i].y == last)continue;
			build(1,1,len);
			int k;
			for(int j=i;j<=n;j=k){
				for(k=j;k<=n&&p[k].y==p[j].y;k++){
					update(1,1,len,p[k].x,p[k].val);
				}
				ans = max(ans,t[1].mm);
			}
			last = p[i].y;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章