题目链接
题意
将所有点划分成两个集合,要求集合$A$中的点没有在集合$B$中的点的右下方,且最大。
思路
我们考虑如果这样的答案存在,可以让所有$A$集合中的点向左画一条线,$B$集合中的点向下画一条线,这样让所有的线没有交点。
我们不妨让一条折线穿过一些$B$集合的点,满足要求,先将点离散化,然后我们枚举上一次这条线的转折点,就可以进行dp。
线段树维护最大值即可。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using namespace std;
const int M = 1e5+10;
ll mx[M<<2],lazy[M<<2];
void up(ll rt){
mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
}
void pushdown(ll rt){
if(lazy[rt]){
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
mx[rt<<1] += lazy[rt];
mx[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
}
void build(ll l,ll r,ll rt){
lazy[rt] = 0; mx[rt] = 0;
if(l == r){
return ;
}
mid;
build(lson); build(rson);
}
void update(ll p,ll c,ll l,ll r,ll rt){
if(l == r){
mx[rt] = max(mx[rt],c);
return ;
}
pushdown(rt);
mid;
if(p <= m) update(p,c,lson);
else update(p,c,rson);
up(rt);
}
void update1(ll L,ll R,ll c,ll l,ll r,ll rt){
if(L > R) return ; //会出现L > R的情况,需要判下
if(L <= l&&R >= r){
mx[rt] += c;
lazy[rt] += c;
return ;
}
pushdown(rt);
mid;
if(L <= m) update1(L,R,c,lson);
if(R > m) update1(L,R,c,rson);
up(rt);
}
ll query(ll L,ll R,ll l,ll r,ll rt){
if(L > R) return 0;
if(L <= l&&R >= r){
return mx[rt];
}
pushdown(rt);
mid;
ll ret = 0;
if(L <= m) ret = max(ret,query(L,R,lson));
if(R > m) ret = max(ret,query(L,R,rson));
return ret;
}
struct node{
ll x,y,a,b;
}v[M];
bool cmp(node aa,node bb){
if(aa.x == bb.x) return aa.y > bb.y;
return aa.x < bb.x;
}
ll t[M];
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF){
ll cnt = 0;
for(ll i = 1;i <= n;i ++){
scanf("%lld%lld%lld%lld",&v[i].x,&v[i].y,&v[i].a,&v[i].b);
t[++cnt] = v[i].y;
}
sort(t+1,t+1+cnt);
sort(v+1,v+1+n,cmp);
ll m = unique(t+1,t+1+cnt)-t-1;
for(ll i = 1;i <= n;i ++)
v[i].y = lower_bound(t+1,t+1+m,v[i].y)-t+1; //离散化时点都向后移一位
m ++; //点后移了一位,长度要+1;
build(1,m,1);
for(ll i = 1;i <= n;i ++){
ll ans = query(1,v[i].y,1,m,1);
update1(v[i].y,m,v[i].b,1,m,1);
update1(1,v[i].y-1,v[i].a,1,m,1);
update(v[i].y,ans+v[i].b,1,m,1);
}
printf("%lld\n",mx[1]);
}
return 0;
}