2019 cattle off more school match first title I make up questions

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;
}

 

Guess you like

Origin www.cnblogs.com/kls123/p/11221471.html