• 雨天的尾巴


    洛谷

    线段树合并模板题

    不说了直接代码分析

    大佬的code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<ctime>
    using namespace std;
    #define ll long long
    #define N 101000
    #define Z 100000
    #define inf 1e9
    #define RG register
    #define re return
    inline ll read(){
        RG ll x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    
    int n,m,top,first[N],ans[N];
    
    struct mona {int nxt,en;}s[N<<1];
    
    struct joker{int nxt,en,op;};
    
    inline void Insert(int x,int y) 
    { 
        s[++top]=(mona){first[x],y};
        first[x]=top; 
    }
    
    struct SeqTree{
        int cnt,ls[N*40],rs[N*40],Max[N*40],id[N*40],rt[N],rab[N*40],tot,top,first[N]; joker s[N<<2]; 
        
        inline void Insert(int x,int y,int op) //差分起始 
        { 
            s[++top]=(joker){first[x],y,op};
            first[x]=top; 
        }
        
        inline int New() 
        {
             if(tot)
             re rab[tot--]; 
            re ++cnt;
        }
        inline void Throw(int x) 
        { 
            rab[++top]=x;
            ls[x]=rs[x]=Max[x]=id[x]=0; 
        }
        inline void Pushup(int x)
        {
            if(Max[ls[x]]>=Max[rs[x]]) 
                Max[x]=Max[ls[x]],id[x]=id[ls[x]];
            else Max[x]=Max[rs[x]],id[x]=id[rs[x]];
        }
        
        inline void Modify(int l,int r,int &x,int pos,int val)
        {
            if(!x) x=New(); 
            if(l==r) 
            { 
                Max[x]+=val;
                id[x]=l;
            }
            else
            {
                int mid=l+r>>1;
                if(pos<=mid) Modify(l,mid,ls[x],pos,val);
                else 
                    Modify(mid+1,r,rs[x],pos,val);
                Pushup(x);
            } 
            if(!Max[x]) id[x]=0;//回收机制处理 
        }
        inline int Merge(int l,int r,int u,int v)//并一波线段树  
        {
            if(!u||!v) return u|v;
            int now=New(),mid=l+r>>1; 
            
            if(l==r) Max[now]=Max[u]+Max[v],id[now]=l;//MAX,id同步 
            else 
            {
                ls[now]=Merge(l,mid,ls[u],ls[v]);
                rs[now]=Merge(mid+1,r,rs[u],rs[v]);
                Pushup(now);
            } 
            Throw(u);
            Throw(v); 
            //biu,扔进垃圾桶 
            re now;
        }
    } T;
    
    struct Tree{
        int top[N],son[N],siz[N],fa[N],dep[N];
        inline void Dfs(int k,int Fa){
            fa[k]=Fa,siz[k]=1,dep[k]=dep[Fa]+1;
            for(RG int i=first[k];i;i=s[i].nxt){
                int en=s[i].en; if(en==Fa) continue ;
                Dfs(en,k),siz[k]+=siz[en];
                if(siz[son[k]]<siz[en]) son[k]=en;
            }   return ;
        }
        inline void Dfs2(int k,int to){
            top[k]=to; if(son[k]) Dfs2(son[k],to);
            for(RG int i=first[k];i;i=s[i].nxt){
                int en=s[i].en; if(en==fa[k]||en==son[k]) continue ;
                Dfs2(en,en);
            }
        }
        inline int Lca(int u,int v){
            while(top[u]!=top[v]){
                if(dep[top[u]]<dep[top[v]]) swap(u,v);
                u=fa[top[u]];
            }   return dep[u]<dep[v]?u:v;
        }
    } S;//LCA树 
    
    inline void Dfs(int k,int fa)
    {
        for(RG int i=first[k];i;i=s[i].nxt) 
        if(s[i].en!=fa) Dfs(s[i].en,k);
        
        for(RG int i=T.first[k];i;i=T.s[i].nxt) 
            T.Modify(1,Z,T.rt[k],T.s[i].en,T.s[i].op);//加入 
            
        ans[k]=T.id[T.rt[k]];
        
        if(S.fa[k])//存在父亲 
            T.rt[S.fa[k]]=T.Merge(1,Z,T.rt[S.fa[k]],T.rt[k]);
            //
            
        re;
    }
    
    int main(){
        freopen("in.txt","r",stdin);
        n=read(),m=read();
        
        for(RG int i=1;i<n;++i)
        {
            int x=read(),y=read();
            Insert(x,y),Insert(y,x);//add边 
        }  
        
        //剖一波 
         S.Dfs(1,0);
         S.Dfs2(1,1);
          
        for(RG int i=1;i<=m;++i)
        {
            int u=read(),v=read(),val=read();
            int lca=S.Lca(u,v),Flca=S.fa[lca];//LCA
            //差分一下 
            T.Insert(u,val,1),T.Insert(v,val,1),T.Insert(lca,val,-1),T.Insert(Flca,val,-1);
        }   
        Dfs(1,0); //总来一起统计 
        for(RG int i=1;i<=n;++i) printf("%d
    ",ans[i]);
    }

    蒟蒻的

    有一点问题就是

    权值线段树

    貌似可以不用离散化

    /*
    while(next second)
    ++love_life;
    */
    #include<bits/stdc++.h>
    #define re return
    #define R register 
    #define inc(i,l,r) for(register int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=1e5+5,maxl=1e5;
    
    int n,m,k,hd[maxn],hide[maxn],X[maxn],Y[maxn],Z[maxn],a[maxn];
    int ans[maxn];
    
    struct node{
        int to,nt;
    }e[maxn<<1];
    inline void add(int x,int y)
    {
        e[++k].to=y;e[k].nt=hd[x];hd[x]=k;
        e[++k].to=x;e[k].nt=hd[y];hd[y]=k;
    }
    
    struct tree
    {
        int first[maxn],top,tot,cnt;
        int rab[maxn*30],rt[maxn*30],id[maxn*30],ls[maxn*30],rs[maxn*30],Max[maxn*30];
        struct LL
        {
            int col,nt,op;
        }st[maxn<<2];
        
        inline void insert(int x,int y,int z)
        //节点X染成y,+-z 
        {
            st[++top].col=y;st[top].nt=first[x];first[x]=top;st[top].op=z;
        }
        
        inline int New()
        {
            int now;
            if(tot)now=rab[tot--];
            else now=++cnt;
            ls[now]=rs[now]=Max[now]=0;
            re now;
        }
        
        inline void Throw(int x)
        {
            rab[++tot]=x;
        }
        
        inline void pushup(int rt)
        {
            if(Max[ls[rt]]<Max[rs[rt]])
                Max[rt]=Max[rs[rt]],id[rt]=id[rs[rt]];
            else 
                Max[rt]=Max[ls[rt]],id[rt]=id[ls[rt]];
        }
        
        inline void Add(int &rt,int l,int r,int pos,int val)
        {
            if(!rt)
                rt=New();
            if(l==r)
            {
                Max[rt]+=val; 
                id[rt]=l;
                re;
            }
            
            int mid=(l+r)>>1;
            if(pos<=mid) Add(ls[rt],l,mid,pos,val);
            else Add(rs[rt],mid+1,r,pos,val);
            pushup(rt);
            if(!Max[rt]) id[rt]=0;
        }
        
        inline int merge(int l,int r,int x,int y)
        {
            if(!x||(!y))re x+y;
            if(l==r)
            {
                Max[x]+=Max[y];
                Throw(y);
                re x;
            }
            
            int mid=(l+r)>>1;
            ls[x]=merge(l,mid,ls[x],ls[y]);
            rs[x]=merge(mid+1,r,rs[x],rs[y]);
            Throw(y);
            pushup(x);
            re x;
        }
        
    
    }T;
    
    struct LCA
    {
        int fa[maxn],top[maxn],son[maxn],size[maxn],dep[maxn];
        
        inline void dfs1(int x)
        {
            dep[x]=dep[fa[x]]+(size[x]=1);
            for(int i=hd[x];i;i=e[i].nt)
            {
                int v=e[i].to;
                if(v==fa[x])continue;
                fa[v]=x;
                dfs1(v);
                size[x]+=size[v];
                if(size[v]>size[son[x]])
                son[x]=v;
            }
        }
        
        inline void dfs2(int x,int topf)
        {
            top[x]=topf;
            if(son[x])
            {
                dfs2(son[x],topf);
                for(int i=hd[x];i;i=e[i].nt)
                {
                    int v=e[i].to;
                    if(!top[v])
                    dfs2(v,v);
                }
            }    
        }
        
        inline int Lca(int x,int y)
        {
            while(top[x]!=top[y])
            {
                if(dep[top[x]]<dep[top[y]])x^=y^=x^=y;
                x=fa[top[x]];
            }
            re dep[x]<dep[y]?x:y;
        }
    }S;
    
    inline void dfs(int x)
    {
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(v==S.fa[x])continue;
            dfs(v);
        }
        
        for(int i=T.first[x];i;i=T.st[i].nt)
            T.Add(T.rt[x],1,maxl,T.st[i].col,T.st[i].op);
        ans[x]=T.id[T.rt[x]];
        
        if(S.fa[x])T.rt[S.fa[x]]=T.merge(1,maxl,T.rt[S.fa[x]],T.rt[x]);
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int x,y,z;
        rd(n),rd(m);
        inc(i,2,n)
        {
            rd(x),rd(y);
            add(x,y);
        }
        
        S.dfs1(1);
        S.dfs2(1,1);
            
        inc(i,1,m)
        {
            rd(X[i]),rd(Y[i]),rd(Z[i]);
            a[i]=Z[i];
        }    
        //离散化
        sort(a+1,a+m+1);
        int N=unique(a+1,a+m+1)-a-1;
        
        inc(i,1,N)hide[i]=a[i];
        
        inc(i,1,m)
        {
            int lca=S.Lca(X[i],Y[i]),flca=S.fa[lca];
            
            int pos=lower_bound(a+1,a+N+1,Z[i])-a;
    
            T.insert(X[i],pos,1);T.insert(Y[i],pos,1);
            T.insert(lca,pos,-1);T.insert(flca,pos,-1);
        }
        
        dfs(1);
        inc(i,1,n)
        printf("%d
    ",hide[ans[i]]);
        re 0;
    }
  • 相关阅读:
    js 正则表达式 test match exec三个方法的异同
    网页使用MD5加密
    解决Google地图和字体api无法加载的问题(转)
    Javascript 的addEventListener()及attachEvent()区别分析
    get与post的区别
    清除浮动的几种方法
    zoom属性(IE私有属性)
    class,id和name的区别
    深夜偷精之反射函数
    jQuery和js区别
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11527341.html
Copyright © 2020-2023  润新知