树剖求助
查看原帖
树剖求助
428449
Amon_Xolotl楼主2023/10/17 21:01
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+3;
inline int read(){
  int x=0,f=1;
  char ch=getchar();
  while(ch>'9'||ch<'0')
  {
    if(ch=='-')
    {
      f=-f;
    }
    ch=getchar();
  }
  while(ch>='0'&&ch<='9')
  {
    x=x*10+ch-'0';
    ch=getchar();
  }
  return x*f;
}
int n,h[N],e[N*2],ne[N*2],tot,m;
ll s[N],col[N];
void add(int a,int b)
{
  e[++tot]=b,ne[tot]=h[a],h[a]=tot;
}
int dep[N],fa[N],size[N],id[N],top[N],son[N],rk[N],cnt;
ll ans1;
void dfs1(int u,int ba)
{
  size[u]=1;
  s[u]=col[u];
  for(int i=h[u];i;i=ne[i])
  {
    int v=e[i];
    if(v!=ba)
    {
      dep[v]=dep[u]+1;
      fa[v]=u;
      dfs1(v,u);
      size[u]+=size[v];
      if(size[son[u]]<size[v])
      {
        son[u]=v;
      }
      s[u]+=s[v];
    }
  }
  ans1+=s[u]*s[u];
}
void dfs2(int u)
{
  id[u]=++cnt;
  rk[cnt]=u;
  if(son[u])
  {
    top[son[u]]=top[u];
    dfs2(son[u]);
  }
  for(int i=h[u];i;i=ne[i])
  {
    int v=e[i];
    if(v!=fa[u]&&v!=son[u])
    {
      top[v]=v;
      dfs2(v);
    }
  }
}
struct Tree
{
  ll sum,lazy;
}tr[N<<2];
void pushup(int rt)
{
  tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
}
void build(int rt,int l,int r)
{
  tr[rt].lazy=0;
  if(l==r)
  {
    tr[rt].sum=s[rk[l]];
    return;
  }
  int mid=(l+r)>>1;
  build(rt<<1,l,mid);
  build(rt<<1|1,mid+1,r);
  pushup(rt);
}
void pushdown(int rt,int l,int r)
{
  if(tr[rt].lazy==0)
  {
    return;
  }
  int mid=(l+r)>>1;
  tr[rt<<1].sum+=tr[rt].lazy*(ll)(mid-l+1),tr[rt<<1|1].sum+=tr[rt].lazy*(ll)(r-mid);
  tr[rt<<1].lazy+=tr[rt].lazy,tr[rt<<1|1].lazy+=tr[rt].lazy;
  tr[rt].lazy=0; 
  return;
}
void modify(int rt,int l,int r,int x,int y,ll v)
{
  if(l>=x&&r<=y)
  {
    tr[rt].sum+=(ll)(r-l+1)*v;
    tr[rt].lazy+=v;
    return;
  }
  int mid=(l+r)>>1;
  pushdown(rt,l,r);
  if(x<=mid)
  {
    modify(rt<<1,l,mid,x,y,v);
  }
  if(y>mid)
  {
    modify(rt<<1|1,mid+1,r,x,y,v);
  }
  pushup(rt);
}
void update(int x,int y,ll v)
{
  while(top[x]!=top[y])
  {
    if(dep[top[x]]<dep[top[y]])
    {
      swap(x,y);
    }
    modify(1,1,n,id[top[x]],id[x],v);
    x=fa[top[x]];
  }
  if(dep[x]<dep[y])
  {
    swap(x,y);
  }
  modify(1,1,n,id[y],id[x],v);
}
ll query(int rt,int l,int r,int x,int y)
{
  if(l>=x&&r<=y)
  {
    return tr[rt].sum;
  }
  int mid=(l+r)>>1;
  pushdown(rt,l,r);
  ll ret=0;
  if(x<=mid)
  {
    ret+=query(rt<<1,l,mid,x,y);
  }
  if(y>mid)
  {
    ret+=query(rt<<1|1,mid+1,r,x,y);
  }
  pushup(rt);
  return ret;
}
ll ask1(int x,int y)
{
  ll ret=0;
  while(top[x]!=top[y])
  {
    if(dep[top[x]]<dep[top[y]])
    {
      swap(x,y);
    }
    ret+=query(1,1,n,id[top[x]],id[x]);
    x=fa[top[x]];
  }
  if(dep[x]<dep[y])
  {
    swap(x,y);
  }
  ret+=query(1,1,n,id[y],id[x]);
  return ret;
}
int main()
{
  n=read(),m=read();
  for(int i=1;i<n;++i)
  {
    int u=read(),v=read();
    add(u,v);
    add(v,u);
  }
  for(int i=1;i<=n;++i)
  {
    cin>>col[i];
  }
  dfs1(1,0);
  top[1]=1,dfs2(1);
  build(1,1,n);
  while(m--)
  {
    int opt=read(),x=read();
    if(opt==1)
    {
      ll y;
      cin>>y;
      y-=col[x];
      s[1]+=y;
      ans1+=(ll)y*y*(ll)(dep[x]-dep[1]+1)+2ll*y*ask1(x,1);
      update(x,1,y);
    }
    else
    {
      cout<<ans1+(ll)(dep[x]-dep[1]+2ll)*s[1]*s[1]-2ll*s[1]*ask1(x,1)<<endl;
    }
  }
  return 0;
}
2023/10/17 21:01
加载中...