首页 > 代码库 > bzoj4353: Play with tree

bzoj4353: Play with tree

Description

给你一棵包含N个节点的树,设每条边一开始的边权为0,现在有两种操作:
 
1)给出参数U,V,C,表示把U与V之间的路径上的边权变成C(保证C≥0)
 
2)给出参数U,V,C,表示把U与V之间的路径上的边权加上C。但是如果U至V之间路径某条边的边权加上C小于0,那么C=这条边的边权的相反数。
 
你需要统计出每次一操作过后树中边权为0的边有多少条。

Input

第一行两个整数N,M,分别表示表示节点个数与操作数。
接下来N-1行每行两个整数X,Y表示X,Y之间有一条边。
接下来M行每行4个整数P,U,V,C,P表示操作类型,U,V,C的意义见题目描述。

Output

输出文件包括M行,每行一个整数,表示边权为0的边的个数。
树链剖分+线段树维护一下区间最小值和个数、覆盖标记、加法标记
#include<cstdio>#include<algorithm>typedef long long i64;const int N=100007;const i64 fil_0=1ll<<60;char buf[6000007],*ptr=buf-1;int _(){    int x=0,c=*++ptr,f=1;    while(c<48)c==-&&(f=-1),c=*++ptr;    while(c>47)x=x*10+c-48,c=*++ptr;    return x*f;}int n,m,es[N*2],enx[N*2],e0[N],ep=2,ans=0;int fa[N],sz[N],dep[N],top[N],son[N],id[N],idp=0;int _l,_r;i64 _a;struct node{    node*lc,*rc;    i64 mn,fil,a;    int L,R,mc;    int c0(){        return mn?0:mc;    }    void _fil(i64 x){        mn=fil=x;        mc=R-L+1;        a=0;    }    void _add(i64 x){        if(fil!=fil_0)fil+=x;        mn+=x;a+=x;    }    void fils(){        if(_l<=L&&R<=_r){            _fil(_a);            return;        }        dn();        int M=L+R>>1;        if(_l<=M)lc->fils();        if(_r>M)rc->fils();        up();    }    void mns(){        if(mn>=_a)return;        if(_l<=L&&R<=_r){            _a=mn;            return;        }        dn();        int M=L+R>>1;        if(_l<=M)lc->mns();        if(_r>M)rc->mns();    }    void adds(){        if(_l<=L&&R<=_r){            _add(_a);            return;        }        dn();        int M=L+R>>1;        if(_l<=M)lc->adds();        if(_r>M)rc->adds();        up();    }    void dn(){        if(a){            lc->_add(a);            rc->_add(a);            a=0;        }        if(fil!=fil_0){            lc->_fil(fil);            rc->_fil(fil);            fil=fil_0;        }    }    void up(){        mn=lc->mn<rc->mn?lc->mn:rc->mn;        mc=0;        if(mn==lc->mn)mc+=lc->mc;        if(mn==rc->mn)mc+=rc->mc;    }}ns[N*2],*np=ns,*rt[N];node*build(int L,int R){    node*w=np++;    w->L=L;w->R=R;    if(L!=R){        int M=L+R>>1;        w->lc=build(L,M);        w->rc=build(M+1,R);        w->up();    }else{        w->mn=0;w->mc=1;        w->fil=fil_0;    }    return w;}#define F(a,b) ans-=a->c0(),a->b(),ans+=a->c0()void fils(int x,int y,i64 c){    int a=top[x],b=top[y];    _a=c;    while(a!=b){        if(dep[a]<dep[b])std::swap(a,b),std::swap(x,y);        _l=id[a],_r=id[x];        F(rt[a],fils);        x=fa[a];a=top[x];    }    if(dep[x]>dep[y])std::swap(x,y);    _l=id[x]+1,_r=id[y];    if(_l<=_r)F(rt[top[x]],fils);}void mns(int x,int y,i64 c){    int a=top[x],b=top[y];    _a=c;    while(a!=b){        if(dep[a]<dep[b])std::swap(a,b),std::swap(x,y);        _l=id[a],_r=id[x];        rt[a]->mns();        x=fa[a];a=top[x];    }    if(dep[x]>dep[y])std::swap(x,y);    _l=id[x]+1,_r=id[y];    if(_l<=_r)rt[top[x]]->mns();}void adds(int x,int y,i64 c){    mns(x,y,-c);    _a*=-1;    int a=top[x],b=top[y];    while(a!=b){        if(dep[a]<dep[b])std::swap(a,b),std::swap(x,y);        _l=id[a],_r=id[x];        F(rt[a],adds);        x=fa[a];a=top[x];    }    if(dep[x]>dep[y])std::swap(x,y);    _l=id[x]+1,_r=id[y];    if(_l<=_r)F(rt[top[x]],adds);}void f1(int w,int pa){    dep[w]=dep[fa[w]=pa]+1;    sz[w]=1;    for(int i=e0[w];i;i=enx[i]){        int u=es[i];        if(u!=pa){            f1(u,w);            sz[w]+=sz[u];            if(sz[u]>sz[son[w]])son[w]=u;        }    }}void f2(int w,int tp){    top[w]=tp;    id[w]=++idp;    if(son[w])f2(son[w],tp);    else rt[tp]=build(id[tp],id[w]);    for(int i=e0[w];i;i=enx[i]){        int u=es[i];        if(u!=fa[w]&&u!=son[w])f2(u,u);    }}int main(){    buf[fread(buf,1,sizeof(buf),stdin)]=0;    n=_();m=_();    for(int i=1,a,b;i<n;++i){        a=_();b=_();        es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;        es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;    }    f1(1,0);f2(1,1);    ans=n-1;    for(int i=0,o,u,v,c;i<m;++i){        o=_();u=_();v=_();c=_();        if(o==1)fils(u,v,c);        else adds(u,v,c);        printf("%d\n",ans);    }    return 0;}

 

bzoj4353: Play with tree