BZOJ 2836 魔法树 链剖裸题~~

正好练练熟练度。。(刷水题谋财害命QAQ)

#include<cstdio>
#include<iostream>
#define ll long long
#define R register ll
#define ls (tr<<1)
#define rs (tr<<1|1)
const int M=100010;
using namespace std;
inline ll g() {
    R ret=0; register char ch; while(!isdigit(ch=getchar())) ; 
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
}
int n,m,tr,cnt,num,mod;
int vr[M<<1],nxt[M<<1],fir[M],dfn[M],pre[M],d[M],sz[M],son[M],top[M],rw[M],w[M];
ll tg[M<<2],sum[M<<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]) {
            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) {sum[tr]=0; return ;}
    R md=(l+r)>>1; build(ls,l,md),build(rs,md+1,r); 
    sum[tr]=sum[ls]+sum[rs];
}
inline void spread(int tr,int len) {
    if(tg[tr]) 
        tg[ls]+=tg[tr],sum[ls]+=(len-(len>>1))*tg[tr],
        tg[rs]+=tg[tr],sum[rs]+=(len>>1)*tg[tr],tg[tr]=0;
}
inline ll query(int tr,int l,int r,int LL,int RR) { R ret=0;
    if(LL<=l&&r<=RR) {return sum[tr];} spread(tr,r-l+1); R md=(l+r)>>1;
    if(LL<=md) ret+=query(ls,l,md,LL,RR);
    if(RR>md) ret+=query(rs,md+1,r,LL,RR); return ret;
}
inline void update(int tr,int l,int r,int LL,int RR,int inc) {
    if(LL<=l&&r<=RR) {tg[tr]+=inc,sum[tr]+=(r-l+1)*inc; return ;}
    spread(tr,r-l+1); R md=(l+r)>>1;
    if(LL<=md) update(ls,l,md,LL,RR,inc);
    if(RR>md) update(rs,md+1,r,LL,RR,inc);
    sum[tr]=sum[ls]+sum[rs];
}
inline void change(int u,int v,int inc) {
    while(top[u]!=top[v]) {
        if(d[top[u]]<d[top[v]]) swap(u,v);
        update(1,1,n,dfn[top[u]],dfn[u],inc);
        u=pre[top[u]];
    } if(dfn[u]>dfn[v]) swap(u,v);
    update(1,1,n,dfn[u],dfn[v],inc);
}
signed main() {
    n=g();
    for(R i=1,u,v;i<n;++i) u=g(),v=g(),add(u,v),add(v,u); cnt=0;
    d[tr]=1; dfs(tr),dfs_(tr,tr); build(1,1,n); m=g();
    for(R i=1;i<=m;++i) { register char ch; while(!isalpha(ch=getchar()));
        R u=g(),v,inc; 
        if(ch=='A') v=g(),inc=g(),change(u,v,inc);
        else if(ch=='Q') printf("%lld\n",query(1,1,n,dfn[u],dfn[u]+sz[u]-1));
    }
}

2019.04.22

posted @ 2019-04-22 13:31  LuitaryiJack  阅读(152)  评论(0编辑  收藏  举报