求调,悬关

P3038 [USACO11DEC] Grass Planting G

_Haoomff_ @ 2024-04-06 08:51:43

rt.

样例都不对。

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
typedef long long ll;
int head[N],nxt[N<<1],V[N<<1],edgenum,tim,size[N],son[N],dep[N],fa[N],top[N],in[N],n,m;
ll a[N],b[N];
struct node{
    int l,r,len;
    ll sum,lazy;
}tree[N<<2];
inline void push_up(int p){
    tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
}
inline void build(int p,int l,int r){
    tree[p].l=l;tree[p].r=r;tree[p].lazy=0;tree[p].len=r-l+1;
    if(l==r){
        tree[p].sum=b[l];
        return;
    }
    int mid=l+(r-l>>1);
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    push_up(p);
}
inline void push_down(int p){
    tree[p<<1].lazy+=tree[p].lazy;
    tree[p<<1|1].lazy+=tree[p].lazy;
    tree[p<<1].sum+=tree[p].lazy*tree[p<<1].len;
    tree[p<<1|1].sum+=tree[p].lazy*tree[p<<1|1].len;
    tree[p].lazy=0;
}
inline void update(int p,ll v,int l,int r){
    if(tree[p].r<l||tree[p].l>r)return;
    if(l<=tree[p].l&&tree[p].r<=r){
        tree[p].sum+=v*tree[p].len;
        if(tree[p].l<tree[p].r)tree[p].lazy+=v;
        return;
    }
    push_down(p);
    update(p<<1,v,l,r);
    update(p<<1|1,v,l,r);
    push_up(p);
}
inline ll query(int p,int l,int r){
    if(tree[p].r<l||tree[p].l>r)return 0LL;
    if(l<=tree[p].l&&tree[p].r<=r)return tree[p].sum;
    push_down(p);
    return query(p<<1,l,r)+query(p<<1|1,l,r);
}
inline void add(int u,int v){
    V[++edgenum]=v;
    nxt[edgenum]=head[u];
    head[u]=edgenum;
}
inline void dfs(int u,int father){
    dep[u]=dep[father]+1;
    fa[u]=father;
    size[u]=1;
    for(int e=head[u];e;e=nxt[e])
        if(V[e]!=father){
            dfs(V[e],u);
            size[u]+=size[V[e]];
            if(size[V[e]]>size[son[u]])son[u]=V[e];
        }
}
inline void dfs1(int u,int t){
    in[u]=++tim;
    b[tim]=a[u];
    top[u]=t;
    if(!son[u])return;
    dfs1(son[u],t);
    for(int e=head[u];e;e=nxt[e])
        if(V[e]!=fa[u]&&V[e]!=son[u])
            dfs1(V[e],V[e]);
}
inline ll query(int x,int y){
    ll res=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        res+=query(1,in[top[x]],in[x]);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y])swap(x,y);
    res+=query(1,in[y],in[x]);
    return res; 
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1,u,v;i<n;++i){
        cin>>u>>v;
        add(u,v);
        add(v,u);
    } 
    dfs(1,0);
    dfs1(1,1);
    build(1,1,n);
    for(int u,v;m--;){
        char op;
        cin>>op>>u>>v;
        if(op=='P')update(1,1,in[u],in[v]);
        else cout<<query(u,v)<<"\n";
    }
    return 0;
}

by yiming_328 @ 2024-06-10 11:42:27

@Haoomff 是边权不是点权呢


by yiming_328 @ 2024-06-10 11:46:09

@Haoomff 因为边权下赋,所以一操作取lca,二操作直接用线段树取子结点点权


|