zoukankan      html  css  js  c++  java
  • 【BZOJ】1537: [POI2005]Aut- The Bus

    【算法】DP+线段树求区间max(二维偏序)

    【题解】

    状态转移方程:f[i]=max(f[j]+v[i]),x[j]<x[i]&&y[j]<y[i]。

    观察j的条件限制显然是二维偏序求最大值,套路化地离散化后一维排序+一维线段树即可解决。

    最后在f[i]中找max,所以不用恢复原序。

    复杂度O(n log n)。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    const int maxn=300010;
    int f[maxn],n,m,k;
    inline int max(int x,int y){return x>y?x:y;}
    struct lshs{int x,ord;}ls[maxn];
    struct cyc{int x,y,v;}a[maxn];
    struct tree{int l,r,mx;}t[maxn*2];
    bool cmps(cyc a,cyc b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    bool cmp(lshs a,lshs b){return a.x<b.x;}
    int read()
    {
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    void lsh(){
        for(int i=1;i<=k;i++)ls[i]=(lshs){a[i].x,i};
        sort(ls+1,ls+k+1,cmp);
        int p=0;
        for(int i=1;i<=k;i++)if(ls[i].x==ls[i-1].x)a[ls[i].ord].x=p;else a[ls[i].ord].x=++p;
        n=p;
        for(int i=1;i<=k;i++)ls[i]=(lshs){a[i].y,i};
        sort(ls+1,ls+k+1,cmp);
        p=0;
        for(int i=1;i<=k;i++)if(ls[i].x==ls[i-1].x)a[ls[i].ord].y=p;else a[ls[i].ord].y=++p;
        m=p;
    }
    void build(int k,int l,int r){
        t[k].l=l;t[k].r=r;
        if(l==r)return;
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    void insert(int k,int x,int y){
        if(t[k].l==t[k].r){t[k].mx=max(t[k].mx,y);}
        else{
            int mid=(t[k].l+t[k].r)>>1;
            if(x<=mid)insert(k<<1,x,y);
            else insert(k<<1|1,x,y);
            t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
        }
    }
    int find(int k,int l,int r){
        if(l<=t[k].l&&t[k].r<=r)return t[k].mx;
        else{
            int mid=(t[k].l+t[k].r)>>1,mx=0;
            if(l<=mid)mx=find(k<<1,l,r);
            if(r>mid)mx=max(mx,find(k<<1|1,l,r));
            return mx;
        }
    }
    int main(){
        n=read();m=read();k=read();
        for(int i=1;i<=k;i++){
            a[i].x=read();a[i].y=read();a[i].v=read();
        }
        lsh();
        sort(a+1,a+k+1,cmps);
        build(1,1,m);
        for(int i=1;i<=k;i++){
            f[i]=find(1,1,a[i].y)+a[i].v;
            insert(1,a[i].y,f[i]);
        }
        int ans=0;
        for(int i=1;i<=k;i++)ans=max(ans,f[i]);
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Maximum Flow Exhaustion of Paths Algorithm
    ubuntu下安装java环境
    visualbox使用(二)
    vxworks一个超级奇怪的错误(parse error before `char')
    February 4th, 2018 Week 6th Sunday
    February 3rd, 2018 Week 5th Saturday
    February 2nd, 2018 Week 5th Friday
    February 1st, 2018 Week 5th Thursday
    January 31st, 2018 Week 05th Wednesday
    January 30th, 2018 Week 05th Tuesday
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7348647.html
Copyright © 2011-2022 走看看