zoukankan      html  css  js  c++  java
  • BZOJ 1036 && Luogu P2590 [ZJOI2008]树的统计 树链剖分

    链剖裸题。。。你值得一做~

    用线段树多维护一个mx,少写一个tag

    #include<cstdio>
    #include<iostream>
    #define ll long long
    #define R register ll
    #define ls (tr<<1)
    #define rs (tr<<1|1)
    using namespace std;
    const int N=100010;
    inline ll g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    }
    int n,m,cnt,num,mod;
    int vr[N<<1],nxt[N<<1],fir[N],dfn[N],pre[N],son[N],d[N],sz[N],top[N],rw[N],w[N];
    ll sum[N<<2],mx[N<<2];
    inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    void dfs(int u) { sz[u]=1; R mx=0;
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(d[v]) continue; pre[v]=u; d[v]=d[u]+1;
            dfs(v); sz[u]+=sz[v]; if(sz[v]>mx) son[u]=v,mx=sz[v];
        }
    }
    void dfs_(int u,int tp) {
        top[u]=tp,dfn[u]=++num,rw[num]=u;
        if(son[u]) dfs_(son[u],tp);
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(v!=pre[u]&&v!=son[u]) dfs_(v,v);
        }
    }
    inline void build(int tr,int l,int r) {
        if(l==r) {mx[tr]=sum[tr]=w[rw[l]]; return ;}
        R md=(l+r)>>1; build(ls,l,md),build(rs,md+1,r);
        sum[tr]=sum[ls]+sum[rs],mx[tr]=max(mx[ls],mx[rs]);
    }
    inline ll queryS(int tr,int l,int r,int LL,int RR) {
        if(LL<=l&&r<=RR) return sum[tr]; R md=(l+r)>>1,ret=0;
        if(LL<=md) ret+=queryS(ls,l,md,LL,RR); if(RR>md) ret+=queryS(rs,md+1,r,LL,RR);
        return ret;
    }
    inline ll queryM(int tr,int l,int r,int LL,int RR) {
        if(LL<=l&&r<=RR) return mx[tr]; R md=(l+r)>>1,ret=-100000000000000;
        if(LL<=md) ret=max(queryM(ls,l,md,LL,RR),ret); if(RR>md) ret=max(queryM(rs,md+1,r,LL,RR),ret);
        return ret;
    }
    inline void update(int tr,int l,int r,int pos,ll inc) {
        if(l==r) {mx[tr]=sum[tr]=inc; return ;}
        R md=(l+r)>>1; if(pos<=md) update(ls,l,md,pos,inc); else update(rs,md+1,r,pos,inc);
        sum[tr]=sum[ls]+sum[rs],mx[tr]=max(mx[ls],mx[rs]);
    }
    inline ll queryTS(int u,int v) { R ret=0;
        while(top[u]!=top[v]) {
            if(d[top[u]]<d[top[v]]) swap(u,v);
            ret+=queryS(1,1,n,dfn[top[u]],dfn[u]);
            u=pre[top[u]];
        } if(dfn[u]>dfn[v]) swap(u,v); ret+=queryS(1,1,n,dfn[u],dfn[v]);
        return ret;
    }
    inline ll queryTM(int u,int v) { R ret=-100000000000000;
        while(top[u]!=top[v]) {
            if(d[top[u]]<d[top[v]]) swap(u,v);
            ret=max(queryM(1,1,n,dfn[top[u]],dfn[u]),ret);
            u=pre[top[u]];
        } if(dfn[u]>dfn[v]) swap(u,v); ret=max(queryM(1,1,n,dfn[u],dfn[v]),ret);
        return ret;
    }
    inline void print(int tr,int l,int r) {
        if(l==r) {printf("%lld %lld ",sum[tr],mx[tr]); return ;} R md=(l+r)>>1;
        print(ls,l,md),print(rs,md+1,r);
    }
    signed main() {
        n=g(); for(R i=1,u,v;i<n;++i) u=g(),v=g(),add(u,v),add(v,u);
        for(R i=1;i<=n;++i) w[i]=g();
        d[1]=top[1]=pre[1]=1; dfs(1),dfs_(1,1); build(1,1,n); m=g();
        for(R i=1;i<=m;++i) { register char ch;
            while(!isalpha(ch=getchar())); ch=getchar(); R u=g(),v=g();
            if(ch=='H') update(1,1,n,dfn[u],v);
            else if(ch=='M') printf("%lld
    ",queryTM(u,v));
            else printf("%lld
    ",queryTS(u,v));
        }
    }

    想想就有些后怕,自己调了一个半小时,结果发现update没有写dfn[u],而写的u。。。

    2019.04.19

  • 相关阅读:
    jquery获取select选中的文本值
    Nginx实战入门教程
    【分享】Jenkins自动化部署全套视频教程
    Jenkins自动化部署入门详细教程
    【分享】nginx负载均衡全套视频教程
    IT从业者疫情之下出路何在
    jmeter控制器(四)
    jmeter控制器(三)
    复述记忆法的初步学习总结
    raspberry-gpio-python(树莓派GPIO与Python编程)
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10738913.html
Copyright © 2011-2022 走看看