1. 程式人生 > >[BZOJ1537/Luogu3431][POI2005]AUT-The Bus

[BZOJ1537/Luogu3431][POI2005]AUT-The Bus

復雜 poi com inline php ble 時間 str math

題目鏈接:

BZOJ1537.

Luogu3431

首先離散化一波,然後以\(x\)為第一關鍵字,\(y\)為第二關鍵字排序。

從前往後掃,設\(f[i]\)表示到達\(i\)站的最多乘客,很容易有轉移方程\(f[i]=max(f[j])+p[i]\),其中\((j\le i),y[j]\le y[i]\)

那麽就可以用線段樹優化。

時間復雜度 \(O(nlog_2n)\)

代碼:

#include <cstdio>
#include <algorithm>

int n,Ans,b[100005],bl;
struct Station
{
    int x,y,p;
    inline bool operator<(const Station &o)const
    {return x==o.x?y<o.y:x<o.x;}
}s[100005];
struct Segment_Tree
{
    int a[400005];
    
    inline void Modify(const int p,const int l,const int r,const int o,const int v)
    {
        if(l==r){a[p]=v;return;}
        const int Mid=(l+r)>>1;
        if(o<=Mid)Modify(p<<1,l,Mid,o,v);
        else Modify(p<<1|1,Mid+1,r,o,v);
        a[p]=std::max(a[p],v);
    }
    
    inline int Query(const int p,const int l,const int r,const int tl,const int tr)
    {
        if(tl<=l&&r<=tr)return a[p];
        int Mid=(l+r)>>1,Res=0;
        if(tl<=Mid)Res=Query(p<<1,l,Mid,tl,tr);
        if(tr>Mid)Res=std::max(Res,Query(p<<1|1,Mid+1,r,tl,tr));
        return Res;
    }
}ST;

int main()
{
    scanf("%*d%*d%d",&n);//Input(n,m are useless)
    for(int i=1;i<=n;++i)scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].p);
    
    for(int i=1;i<=n;++i)b[i]=s[i].x;
    std::sort(b+1,b+n+1),bl=std::unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;++i)s[i].x=std::lower_bound(b+1,b+bl+1,s[i].x)-b;
    
    for(int i=1;i<=n;++i)b[i]=s[i].y;
    std::sort(b+1,b+n+1),bl=std::unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;++i)s[i].y=std::lower_bound(b+1,b+bl+1,s[i].y)-b;
    
    std::sort(s+1,s+n+1);
    for(int i=1;i<=n;++i)ST.Modify(1,1,n,s[i].y,ST.Query(1,1,n,1,s[i].y)+s[i].p);
    printf("%d\n",ST.Query(1,1,n,1,n));
    return 0;
}

[BZOJ1537/Luogu3431][POI2005]AUT-The Bus