I题 Points Division
Meaning of the questions:
You n points, each point has coordinates (xi, yi) and attributes (ai, bi), the point set is divided into two sets,
A set of arbitrary point i and point B set j, allowed xi> = xj and Yi <= YJ .
A set point value of the right to use AI , B the right to use the set point value B I , requirements:
Ideas:
May be a crease upwardly from the bottom of these points are divided into two groups, A polyline is a set of upper left, lower right set B, polyline point also belongs to set B
DP [i] representative of maximum weight and the current point i at the fold line
So for the current point i is:
Prior to the point i, y-coordinate yi of the point of less than dp [i] AI weight should be added (as when those points on the polyline points, the current i will be classified as a point A set)
is greater than the y-coordinate yi of the point DP [i] should be added weights bi (since that is the point when off line, the current i will be classified as a point set B)
Calculating dp current point [I], because the fold line from the bottom up, then certainly by the current point below the weight point and the maximum point max (dp [j]) turning, then dp [i] = max (dp [j] + bi;
Finally, take the weight and maximum
Here you can find the need to push the update interval, the interval value most, single-point update, it can be directly used to maintain the tree line.
To pay more attention to a height of 0 points for the polyline start point, so the first point there is a point of reference, or can not count the first case of a point in the polyline and polyline contribution.
Implementation code:
#include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid ll m = (l + r) >> 1 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+1,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; }