zoukankan      html  css  js  c++  java
  • F. Pathwalks动态开辟线段树

    题意:n点m边,然后要求走最多的路,走路的时候经过的边权必须是严格递增。

    解法1:传统的区间更新

    解法2:发现区间更新只是对两个固定的点所延长形成的区间段,所以问题可以退化成单点更新单点查询。

    然后动态开辟线段树就行了

    线段树有1e5个然后每个都是权值线段树

    解法一所需要的空间会比解法二大很多很多,甚至一度以为我写错了.....

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e5+88;
    int rt[N],L[N*25],R[N*25],V[N*25],lz[N*25];
    int n,m,tot;    
    void update(int &k,int pos,int l,int r,int y){
        if(!k) k=++tot;
        if(l>=pos) {
            V[k]=max(y,V[k]);
            lz[k]=max(y,lz[k]);
            return;
        }
        if(lz[k]) {
            if(!L[k]) L[k]=++tot;if(!R[k]) R[k]=++tot;
            lz[L[k]]=max(lz[L[k]],lz[k]);
            lz[R[k]]=max(lz[k],lz[R[k]]);
            V[L[k]]=max(V[L[k]],lz[k]);
            V[R[k]]=max(V[R[k]],lz[k]);
            lz[k]=0;
        }
        int m=(l+r)>>1;
        if(pos<=m) update(L[k],pos,l,m,y);
        update(R[k],pos,m+1,r,y);
        V[k]=max(V[L[k]],V[R[k]]);
    }
    int query(int l,int r,int w,int k){
        if(!k) return 0;
        if(r<=w) return V[k];
        int m=(l+r)>>1;
        if(lz[k]) {
            if(!L[k]) L[k]=++tot;if(!R[k]) R[k]=++tot;
            lz[L[k]]=max(lz[L[k]],lz[k]);
            lz[R[k]]=max(lz[k],lz[R[k]]);
            V[L[k]]=max(V[L[k]],lz[k]);
            V[R[k]]=max(V[R[k]],lz[k]);
            lz[k]=0;
        }
        int ans=query(l,m,w,L[k]);
        if(w>m) ans=max(ans,query(m+1,r,w,R[k]));
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&m);
        int x,y,z,ans=0;
        for(int i=1;i<=m;++i) {
            scanf("%d%d%d",&x,&y,&z);
            z+=10;
            int Q=query(1,100020,z-1,rt[x])+1;
            ans=max(ans,Q);
            update(rt[y],z,1,100020,Q);
        }
        printf("%d
    ",ans);
    }
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e5+88;
    int rt[N],L[N*20],R[N*20],V[N*20];
    int n,m,tot;    
    void update(int &k,int pos,int l,int r,int y){
        if(!k) k=++tot;
        V[k]=max(V[k],y);
        if(l==r) return;
        int m=(l+r)>>1;
        if(pos<=m) update(L[k],pos,l,m,y);
        else update(R[k],pos,m+1,r,y);
    }
    int query(int l,int r,int w,int k){
        if(!k) return 0;
        if(l==r) return V[k];
        int m=(l+r)>>1;
        if(w<=m) return query(l,m,w,L[k]);
        else return max(V[L[k]],query(m+1,r,w,R[k]));
    }
    int main(){
        scanf("%d%d",&n,&m);
        int x,y,z,ans=0;
        for(int i=1;i<=m;++i) {
            scanf("%d%d%d",&x,&y,&z);
            z+=10;
            int Q=query(1,100020,z-1,rt[x])+1;
            ans=max(ans,Q);
            update(rt[y],z,1,100020,Q);
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    杜教筛瞎扯
    网络流 24 题 解题报告
    多项式重工业修炼日志
    c#与js中10进制16进制的转化,记录防忘
    如何在RichTextBox中改变多个字符串的颜色以及字体
    C#TreeView控件遍历文件夹下所有子文件夹以及文件
    自己用c语言实现字符串处理库函数以及扩展
    gcc for windows(mingw)编译多个c文件
    迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)
    spring web mvc中遇到的错误以及学习小记(持续记录)
  • 原文地址:https://www.cnblogs.com/mfys/p/8796999.html
Copyright © 2011-2022 走看看