nove.15 [HAOI2015]树上操作

[HAOI2015]树上操作
树剖板题
第一遍W2RE8
调了半天发现操作1把要更改的w值打成1去了
大寄大力今晚GG

然后变成A3RE7
你谷说segmentation fault
想着改一下数组范围,突然看到线段树忘*4
大寄大力今晚GG

然后A了
然后认真地(作死地)把#define int long long删了
(希望能写更严谨的代码)
A2W8

稍微调了下几个地方:
增加long long的输入
更改值的类型改成long long(以前居然忘了)
然后就过了
真好呢

总共用时1个半小时

ACcode
仔细啊大哥

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define llin llRead()
typedef long long ll;

int in{
    int i=0,f=1; char ch=0;
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') f=-1, ch=getchar();
    while('0'<=ch&&ch<='9') i=(i<<1)+(i<<3)+ch-48, ch=getchar();
    return i*f;
}

ll llin{
    ll i=0,f=1; char ch=0;
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') f=-1, ch=getchar();
    while('0'<=ch&&ch<='9') i=(i<<1)+(i<<3)+ch-48, ch=getchar();
    return i*f;
}

const int N=1e5+5;
int n,m;
vector<int>G[N];
int faz[N],son[N],top[N],dfn[N],idx[N],siz[N],cnt,dep[N];
ll tre[N<<2],laz[N<<2],a[N];

void DFS1(int u,int fa){
    faz[u]=fa;
    siz[u]=1;
    dep[u]=dep[fa]+1;
    for(auto v:G[u]){
        if(v==fa) continue;
        DFS1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]<siz[v]) son[u]=v;
    }
}

void DFS2(int u,int tp){
    top[u]=tp;
    dfn[u]=++cnt;
    idx[cnt]=u;
    if(!son[u]) return;
    DFS2(son[u],tp);
    for(auto v:G[u]){
        if(v==son[u]||v==faz[u]) continue;
        DFS2(v,v);
    }
}

#define lch p<<1
#define rch p<<1|1

void push_up(int p){
    tre[p]=tre[lch]+tre[rch];
}

void push_down(int p,int l,int r){
    if(!laz[p]) return;
    int mid=l+r>>1;
    tre[lch]+=laz[p]*(mid-l+1);
    laz[lch]+=laz[p];
    tre[rch]+=laz[p]*(r-mid);
    laz[rch]+=laz[p];
    laz[p]=0;
    return;
}

void build(int p,int l,int r){
    if(l==r){
        tre[p]=a[idx[l]];
        return;
    }
    int mid=l+r>>1;
    build(lch,l,mid);
    build(rch,mid+1,r);
    push_up(p);
}

ll query(int p,int l,int r,int L,int R){
    if(L<=l&&r<=R) return tre[p];
    push_down(p,l,r);
    int mid=l+r>>1;
    ll res=0;
    if(L<=mid) res+=query(lch,l,mid,L,R);
    if(mid<R) res+=query(rch,mid+1,r,L,R);
    return res;
}

void update(int p,int l,int r,int L,int R,ll w){
    if(L<=l&&r<=R){
        tre[p]+=w*(r-l+1);
        laz[p]+=w;
        return;
    }
    push_down(p,l,r);
    int mid=l+r>>1;
    if(L<=mid) update(lch,l,mid,L,R,w);
    if(mid<R) update(rch,mid+1,r,L,R,w);
    push_up(p);
}

#undef lch
#undef rch

ll Query(int u){
    ll ans=0;
    while(top[u]!=1){
        ans+=query(1,1,n,dfn[top[u]],dfn[u]);
        u=faz[top[u]];
    }
    ans+=query(1,1,n,1,dfn[u]);
    return ans;
}

int main(){

    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);

    n=in,m=in;
    for(int i=1;i<=n;++i) a[i]=llin;

    for(int i=1;i<n;++i){
        int u=in,v=in;
        G[u].push_back(v);
        G[v].push_back(u);
    }

    DFS1(1,0);
    DFS2(1,1);
    build(1,1,n);

    for(int i=1;i<=m;++i){
        int opt=in;
        switch(opt){
            case 3:{
                int x=in;
                printf("%lld\n",Query(x));
                break;
            }
            case 2:{
                int x=in;
                ll w=llin;
                update(1,1,n,dfn[x],dfn[x]+siz[x]-1,w);
                break;
            }
            case 1:{
                int x=in;
                ll w=llin;
                update(1,1,n,dfn[x],dfn[x],w);
                break;
            }
        }
    }

    return 0;
    
}
posted @ 2022-11-15 17:31  antimo  阅读(19)  评论(0)    收藏  举报