• 【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
  • 相关阅读:
    ubuntu shell插件
    通过更改服务器解决双系统ubuntu时间+8
    ubuntu安装mysql遇到的问题
    05 面向对象:构造方法&static&继承&方法 &final
    electron 大体结构
    js时间Date对象介绍及解决getTime转换为8点的问题
    Fiddler命令行和HTTP断点调试
    使用HTTP头去绕过WAF(bypasswaf)
    Linux下php5.3.3安装mcrypt扩展
    Error: Cannot find a valid baseurl for repo: epel
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7348647.html
Copyright © 2020-2023  润新知