有人调树剖嘛awa
查看原帖
有人调树剖嘛awa
210719
Violet___Evergarden楼主2021/9/25 12:32

没过样例

#include <iostream>
#define int long long
using namespace std;
const int kMaxN=100001;
struct SLPF
{
  int heavyson,deep,size,top,father,newid;
}s[kMaxN*2];
struct XDS
{
  int l,r;
  int val,add;
}tr[kMaxN*4];
struct EDGE
{
  int to,nt;
}e[kMaxN*2];
int cnt,hd[kMaxN];
int n,m;
int a[kMaxN],b[kMaxN],num;
void Build(int where,int l,int r)
{
  tr[where].l=l;
  tr[where].r=r;
  if(l==r)
  {
    tr[where].val=b[l];
    return;
  }
  int mid=(l+r)/2;
  Build(where*2,l,mid);
  Build(where*2+1,mid+1,r);
  tr[where].val=tr[where*2].val+tr[where*2+1].val;
}
void Solve(int where)
{
  tr[where*2].val+=tr[where].add*(tr[where*2].r-tr[where*2].l+1);
  tr[where*2+1].val+=tr[where].add*(tr[where*2+1].r-tr[where*2+1].l+1);
  tr[where*2].add+=tr[where].add;
  tr[where*2+1].add+=tr[where].add;
  tr[where].add=0;
}
void Update(int where,int l,int r,int k)
{
  if(tr[where].l>=l&&tr[where].r<=r)
  {
    tr[where].val+=k*(tr[where].r-tr[where].l+1);
    tr[where].add+=k;
    return;
  }
  Solve(where);
  int mid=(tr[where].l+tr[where].r)/2;
  if(mid>=l)
  {
    Update(where*2,l,r,k);
  }
  if(mid<r)
  {
    Update(where*2+1,l,r,k);
  }
  tr[where].val=tr[where*2].val+tr[where*2+1].val;
}
int GetSum(int where,int l,int r)
{
  if(tr[where].l>=l&&tr[where].r<=r)
  {
    return tr[where].val;
  }
  Solve(where);
  int mid=(tr[where].l+tr[where].r)/2,sum=0;
  if(mid>=l)
  {
    sum+=GetSum(where*2,l,r);
  }
  if(mid<r)
  {
    sum+=GetSum(where*2+1,l,r);
  }
  return sum;
}
void Add(int a,int b)
{
  e[++cnt].to=b;
  e[cnt].nt=hd[a];
  hd[a]=cnt;
}
void dfs1(int now,int last)
{
  s[now].deep=s[last].deep+1;
  s[now].father=last;
  s[now].size=1;
  int maxson=0;
  for(int i=hd[now];i;i=e[i].nt)
  {
    if(e[i].to==last)continue;
    dfs1(e[i].to,now);
    s[now].size+=s[e[i].to].size;
    if(s[e[i].to].size>maxson)
    {
      maxson=s[e[i].to].size;
      s[now].heavyson=e[i].to;
    }
  }
}
void dfs2(int now,int top)
{
  s[now].top=top;
  s[now].newid=++num;
  b[num]=a[now];
  if(s[now].heavyson==0)return;
  dfs2(s[now].heavyson,top);
  for(int i=hd[now];i;i=e[i].nt)
  {
    if(e[i].to==s[now].heavyson||e[i].to==s[now].father)continue;
    dfs2(e[i].to,e[i].to);
  }
}
int GetAns(int x,int y)
{
  int ans=0;
  while(s[x].top!=s[y].top)
  {
    if(s[s[x].top].deep<s[s[y].top].deep)
    {
      swap(x,y);
    }
    ans+=GetSum(1,s[s[x].top].newid,s[x].newid);
    x=s[s[x].top].father;
  }
  if(s[x].deep>s[y].deep)
  {
    swap(x,y);
  }
  ans+=GetSum(1,s[x].newid,s[y].newid);
  return ans;
}
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
  cin>>a[i];
}
for(int i=1;i<n;i++)
{
  int a,b;
  cin>>a>>b;
  Add(a,b);
  Add(b,a);
}
dfs1(1,0);
dfs2(1,1);
Build(1,1,n);
while(m--)
{
  int op;
  cin>>op;
  if(op==1)
  {
    int x,a;
    cin>>x>>a;
    Update(1,s[x].newid,s[x].newid,a);
  }
  else if(op==2)
  {
    int x,a;
    cin>>x>>a;
    Update(1,s[x].newid,s[x].newid+s[x].size-1,a);
  }
  else
  {
    int x;
    cin>>x;
    cout<<GetAns(s[1].newid,s[x].newid)<<"\n";
  }
}
return 0;
}
2021/9/25 12:32
加载中...