2019牛客暑期多校训练营 第一场 I Points Division(dp+线段树优化)

 

题解哈

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 100005;
struct NO {
	int l,r;
	ll lazy,mx;
} node[maxn<<2+5];
struct NO2 {
	ll x,y,a,b;
} no[maxn];
int  t[maxn];
int cmp(NO2 a,NO2 b) {
	if(a.x==b.x)return a.y>b.y;
	else return a.x<b.x;
}
void build(int p,int l,int r) {
	node[p].l = l;
	node[p].r = r;
	node[p].lazy = 0;
	node[p].mx = 0;
	if(l==r)return ;
	int mid = (l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
}
void spread(int p) {
	if(node[p].lazy) {
		ll lazy = node[p].lazy;
		node[p].lazy = 0;
		node[p*2].mx+=lazy;
		node[p*2].lazy+=lazy;
		node[p*2+1].mx+=lazy;
		node[p*2+1].lazy+=lazy;
	}
}
void update(int p,int l,int r,ll v) {
	if(node[p].l>=l&&node[p].r<=r) {
		node[p].mx+=v;
		node[p].lazy+=v;
		return ;
	}
	spread(p);
	int mid = (node[p].l+node[p].r)>>1;
	if(l<=mid) update(p*2,l,r,v);
	if(r>mid) update(p*2+1,l,r,v);
	node[p].mx = max(node[p*2].mx,node[p*2+1].mx);
}
void update2(int p,int l,int r,ll v) {
	if(node[p].l==node[p].r) {
		node[p].mx=max(node[p].mx,v);
		return ;
	}
	spread(p);
	int mid = (node[p].l + node[p].r)>>1;
	if(l<=mid) update2(p*2,l,r,v);
	if(r>mid) update2(p*2+1,l,r,v);
	node[p].mx = max(node[p*2].mx,node[p*2+1].mx);
}
ll query(int p,int l,int r) {
	if(l<=node[p].l&&node[p].r<=r) {
		return node[p].mx;
	}
	spread(p);
	ll ans = 0;
	int mid = node[p].l +node[p].r>>1;
	if(l<=mid)ans=max(ans,query(p*2,l,r));
	if(r>mid)ans=max(ans,query(p*2+1,l,r));
	return ans;
}
int main() {
	ll n,cnt,m;
	while(scanf("%lld",&n)==1){
		cnt = 0;	m= 0;
		for(int i=1; i<=n; i++) {
			scanf("%lld%lld%lld%lld",&no[i].x,&no[i].y,&no[i].a,&no[i].b);
			t[++cnt] = no[i].y;
		}
		sort(no+1,no+n+1,cmp);
		sort(t+1,t+cnt+1);
		m = unique(t+1,t+cnt+1)- t-1;
		for(int i=1; i<=n; i++)
			no[i].y = lower_bound(t+1,t+m+1,no[i].y) - t + 1;//离散化增加虚点 表示贴在下面的线
		m++;
		build(1,1,m+1);
		for(int i =1; i<=n; i++) {
			ll ans  = query(1,1,no[i].y);
			update(1,1,no[i].y-1,no[i].a);
			update(1,no[i].y+1,m,no[i].b);
			update2(1,no[i].y,no[i].y,ans+no[i].b);
		}
		printf("%lld\n",node[1].mx);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wym_king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值