两个log可以树链剖分
day2听课时惊闻一个log的做法
但我打low了,并不快...
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define V G[p].v
using namespace std;
typedef long long ll;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(ll &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void write(ll x)
{
char s[50],len=0;
if (x==0) { putchar('0'); return; }
if (x<0) putchar('-'),x=-x;
while (x) s[++len]=x%10+'0',x/=10;
for (int i=len;i;i--) putchar(s[i]);
}
const int N=100005;
#define lowbit(x) ((x)&-(x))
struct BIT{
ll maxn,c[N];
inline void init(int n){
maxn=n;
}
inline void add(ll x,ll r){
for (int i=x;i<=maxn;i+=lowbit(i))
c[i]+=r;
}
inline void add(ll l,ll r,ll x){
add(l,x); add(r+1,-x);
}
inline ll query(ll x){
ll ret=0;
for (int i=x;i;i-=lowbit(i))
ret+=c[i];
return ret;
}
}bit1,bit2;
struct edge{
int u,v,next;
};
edge G[N*2];
int head[N],num;
inline void add(int u,int v,int p)
{
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
ll n,Q,w[N];
int clk,size[N],fat[N],depth[N],tid[N],last[N];
inline int dfs(int u,int fa)
{
size[u]=1; fat[u]=fa; depth[u]=depth[fa]+1;
tid[u]=++clk;
for (int p=head[u];p;p=G[p].next)
if (V!=fa)
size[u]+=dfs(V,u);
last[u]=tid[u]+size[u]-1;
return size[u];
}
int main()
{
ll x,y,order,ans;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(Q); bit1.init(n); bit2.init(n);
for (int i=1;i<=n;i++) read(w[i]);
for (int i=1;i<n;i++) read(x),read(y),add(x,y,++num),add(y,x,++num);
dfs(1,0);
for (int i=1;i<=n;i++) bit1.add(tid[i],last[i],w[i]);
while (Q--)
{
read(order);
if (order==1)
{
read(x); read(y);
bit1.add(tid[x],last[x],y);
}
else if (order==2)
{
read(x); read(y);
bit1.add(tid[x],last[x],-(depth[x]-1)*y);
bit2.add(tid[x],last[x],y);
}
else if (order==3)
{
read(x);
write(bit1.query(tid[x])+bit2.query(tid[x])*depth[x]); putchar('\n');
}
}
return 0;
}