[CF115E]Linear Kingdom Races

[CF115E]Linear Kingdom Races

题目大意:

\(n(n\le10^5)\)个物品,编号为\(1\sim n\)。选取第\(i\)个物品需要\(c_i\)的代价。另外有\(m(m\le10^5)\)个条件,表示若\(l_i\sim r_i\)间的物品全部选择,可以获得\(p_i\)的收益。求最大收益。

思路:

\(f[i]\)表示考虑完前\(i\)个物品是否选取能获得的最大收益。

转移方程为\(f[i]=\max\{f[j]-\texttt{cost}(j+1,i)+\texttt{profit}(j+1,i)\}\)

使用线段树优化即可。

时间复杂度\(\mathcal O((n+m)\log n)\)

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
    register char ch;
    while(!isdigit(ch=getchar()));
    register int x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return x;
}
typedef long long int64;
const int N=2e5+1,M=2e5;
int c[N];
int64 f[N];
struct Segment {
    int l,r,p;
    bool operator < (const Segment &rhs) const {
        return r<rhs.r;
    }
};
Segment s[M];
class SegmentTree {
    #define _left <<1
    #define _right <<1|1
    #define mid ((b+e)>>1)
    private:
        int64 val[N<<2],tag[N<<2];
        void push_up(const int &p) {
            val[p]=std::max(val[p _left],val[p _right]);
        }
        void push_down(const int &p) {
            if(tag[p]==0) return;
            tag[p _left]+=tag[p];
            tag[p _right]+=tag[p];
            val[p _left]+=tag[p];
            val[p _right]+=tag[p];
            tag[p]=0;
        }
    public:
        void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const int64 &x) {
            if(b==l&&e==r) {
                val[p]+=x;
                tag[p]+=x;
                return;
            }
            push_down(p);
            if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x);
            if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x);
            push_up(p);
        }
        int64 query(const int &p,const int &b,const int &e,const int &l,const int &r) {
            if(b==l&&e==r) return val[p];
            push_down(p);
            int64 ret=0;
            if(l<=mid) ret=std::max(ret,query(p _left,b,mid,l,std::min(mid,r)));
            if(r>mid) ret=std::max(ret,query(p _right,mid+1,e,std::max(mid+1,l),r));
            return ret;
        }
    #undef _left
    #undef _right
    #undef mid
};
SegmentTree t;
int main() {
    const int n=getint(),m=getint();
    for(register int i=1;i<=n;i++) c[i]=getint();
    for(register int i=0;i<m;i++) {
        const int l=getint(),r=getint(),p=getint();
        s[i]=(Segment){l,r,p};
    }
    std::sort(&s[0],&s[m]);
    for(register int i=1,j=0;i<=n;i++) {
        t.modify(1,0,n,0,i-1,-c[i]);
        for(;j<m&&s[j].r<=i;j++) {
            t.modify(1,0,n,0,s[j].l-1,s[j].p);
        }
        f[i]=std::max(f[i-1],t.query(1,0,n,0,i-1));
        t.modify(1,0,n,i,i,f[i]);
    }
    printf("%lld\n",f[n]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/skylee03/p/9380148.html