zoukankan      html  css  js  c++  java
  • 数对

    题解

    算是历史遗留问题的解决

    之前队长快跑看题解很迷糊,觉得似懂非懂的,AC但是很水,最后代码都不是我的,是$王_{drink_{grass}}$的

    现在总算会了

    首先题目中条件就是$max(a)<=b_i$

    暴力dp就是$f[i][j]$表示考虑了前$i$个位置最大值为$j$时权值最大是多少

    于是分情况讨论

    1.$a_i>b_i$

    因为要满足$max(a)<=b_i$所以$f[i][a[i]]=max(f[i-1][1],f[i-1][2],,,,,f[i-1][b[i]])+val$这些位置最大值都会改变为$a[i]$

    2.$a_i<b_i$

    因为要满足$max(a)<=b_i$显然在$a_i--b_i$之间$f[i-1][a[i]]--f[i-1][b[i]]$之间最大值不会变直接+val即可

    在$1--a_{i-1}$,最大值变为$a[i]$,于是就有了$f[i][a[i]]=max(f[i-1][1],f[i-1][2],,,,,f[i-1][a[i-1]])+val$

    可以用线段树维护

    $f[i][a[i]]=max(f[i-1][1],f[i-1][2],,,,,f[i-1][b[i]])+val$

    $f[i][a[i]]=max(f[i-1][1],f[i-1][2],,,,,f[i-1][a[i-1]])+val$

    就是区间最大值,单点赋值

    $f[i-1][a[i]]+val--f[i-1][b[i]]+val$

    就是区间+

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 12000000
    ll lsh[A];
    ll n,maxn,len=0,cnt=0,q;
    struct node{
        ll a,b,w;
        friend bool operator < (const node &c,const node &d){
            return ((c.a+c.b)==(d.a+d.b))?(c.b<d.b):((c.a+c.b)<(d.a+d.b));
        }
    }s[A];
    struct tree{
        ll l,r,f,val;
    }tr[A];
    void up(ll x){
        tr[x].val=max(tr[x<<1].val,tr[x<<1|1].val);
    }
    void down(ll x){
        tr[x<<1].f+=tr[x].f;
        tr[x<<1|1].f+=tr[x].f;
        tr[x<<1].val+=tr[x].f;
        tr[x<<1|1].val+=tr[x].f;
        tr[x].f=0;
    }
    void built(ll x,ll l,ll r){
        tr[x].l=l,tr[x].r=r;
        if(tr[x].l==tr[x].r){
            tr[x].val=0;
            return ;
        }
        ll mid=(l+r)>>1;
        built(x<<1,l,mid);
        built(x<<1|1,mid+1,r);
        up(x);
    }
    void seg_max(ll x,ll l,ll r){
        if(l>r) return;
        if(tr[x].f) down(x);
        if(tr[x].l>=l&&tr[x].r<=r){
            maxn=max(maxn,tr[x].val);
    //        maxn=tr[x].val;
            return ;
        }    
        ll mid=(tr[x].l+tr[x].r)>>1;
        if(mid>=l) seg_max(x<<1,l,r);
        if(mid<r) seg_max(x<<1|1,l,r);
    }
    void change(ll x,ll ooo,ll val){
        if(tr[x].l==tr[x].r) {
            tr[x].val=max(tr[x].val,val);
            return ;
        }
        if(tr[x].f) down(x);
        ll mid=(tr[x].l+tr[x].r)>>1;
        if(ooo<=mid) change(x<<1,ooo,val);
        else change(x<<1|1,ooo,val);
        up(x);
    }
    void seg_change(ll x,ll l,ll r,ll val){
        if(l>r) return;
        if(tr[x].f) down(x);
        if(tr[x].l>=l&&tr[x].r<=r){
            tr[x].val+=val;
            tr[x].f+=val;
            return ;
        }
        ll mid=(tr[x].l+tr[x].r)>>1;
        if(mid>=l) seg_change(x<<1,l,r,val);
        if(mid<r) seg_change(x<<1|1,l,r,val);
        up(x);
    }
    int main(){
        scanf("%lld",&n);
        for(ll i=1;i<=n;i++)
            scanf("%lld%lld%lld",&s[i].a,&s[i].b,&s[i].w),lsh[++cnt]=s[i].a,lsh[++cnt]=s[i].b;
        sort(lsh+1,lsh+cnt+1);
        len=unique(lsh+1,lsh+cnt+1)-lsh-1;
        for(ll i=1;i<=n;i++){
            s[i].a=lower_bound(lsh+1,lsh+len+1,s[i].a)-lsh;
            s[i].b=lower_bound(lsh+1,lsh+len+1,s[i].b)-lsh;
        }
        sort(s+1,s+n+1);
        built(1,1,len);
        for(ll i=1;i<=n;i++){
            if(s[i].a>s[i].b){
                maxn=0;
                seg_max(1,1,s[i].b);
                change(1,s[i].a,s[i].w+maxn);
            }
            else {
                seg_change(1,s[i].a,s[i].b,s[i].w);
                maxn=0;
                seg_max(1,1,s[i].a-1);
                change(1,s[i].a,s[i].w+maxn);
            }
        }
        maxn=0;
        seg_max(1,1,len);
        printf("%lld
    ",maxn);
    }
    View Code
  • 相关阅读:
    kafka-->storm-->mongodb
    zuul filter
    使用Spring Cloud Feign
    kafka客户端发布record(消息)
    kafka java api消费者
    kafka java api生产者
    kafka安装和使用
    多线程分析
    springboot入门
    centos7上svn安装
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11758871.html
Copyright © 2011-2022 走看看