bzoj 4034
注意longlong 注意数组大小
辣鸡线段树大小!!!QAQ
#include
#include
#include
#include
#define N 100002
#define LL long long
#define ls x<<1
#define rs x<<1|1
using namespace std;
int n,m,tot=0,df=0;
int head[5*N],to[5*N],nxt[5*N],dfn[N];
int sz[N],tp[N],son[N],de[N],fa[N],ed[N];
LL tree[8*N],v[N],lazy[8*N];
void link(int x,int y)
{
nxt[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
void dfs(int x)
{
sz[x]=1;
for (int i=head[x];i;i=nxt[i])
{
int t=to[i];
if (t==fa[x]) continue;
de[t]=de[x]+1;
fa[t]=x;
dfs(t);
sz[x]+=sz[t];
if (sz[t]>sz[son[x]]) son[x]=t;
}
}
void dfs1(int x,int top)
{
dfn[x]=++df,tp[x]=top;
if (son[x]) dfs1(son[x],top);
for (int i=head[x];i;i=nxt[i])
{
int t=to[i];
if (t==fa[x]||t==son[x]) continue;
dfs1(t,t);
}
ed[x]=df;
}
void down (int x,int l,int r)
{
int mid=(r+l)>>1;
tree[ls]+=lazy[x]*(mid-l+1);
tree[rs]+=lazy[x]*(r-mid);
lazy[ls]+=lazy[x];
lazy[rs]+=lazy[x];
lazy[x]=0;
}
void update(int x,int l,int r,int ll,int rr,LL w)
{
if (l!=r) down(x,l,r);
if (ll<=l&&r<=rr)
{
tree[x]+=w*(r-l+1);
lazy[x]=w;
return ;
}
int mid=(l+r)>>1;
if (ll<=mid) update(ls,l,mid,ll,rr,w);
if (rr>mid) update(rs,mid+1,r,ll,rr,w);
tree[x]=tree[ls]+tree[rs];
}
LL query(int x,int l,int r,int ll,int rr)
{
if (l!=r) down(x,l,r);
if (ll<=l&&r<=rr) return tree[x];
int mid=(l+r)>>1;
LL ans=0;
if (ll<=mid) ans+=query(ls,l,mid,ll,rr);
if (rr>mid) ans+=query(rs,mid+1,r,ll,rr);
return ans;
}
LL lca(int x)
{
LL ans=0;
while (tp[x]!=1)
{
ans+=query(1,1,n,dfn[tp[x]],dfn[x]);
x=fa[tp[x]];
}
ans+=query(1,1,n,1,dfn[x]);
return ans;
}
int main()
{
scanf ("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf ("%lld",&v[i]);
for (int i=1;iint x,y;
scanf ("%d%d",&x,&y);
link(x,y);
link(y,x);
}
de[1]=1;
dfs(1),dfs1(1,1);
for (int i=1;i<=n;++i) update(1,1,n,dfn[i],dfn[i],v[i]);
for (int i=1;i<=m;++i)
{
//cout<1,1,n,dfn[2],dfn[2])<<"**"<int fl=1;
scanf ("%d",&fl);
if (fl==1)
{
int x,a;
scanf ("%d%d",&x,&a);
update(1,1,n,dfn[x],dfn[x],a);
}
if (fl==2)
{
int x,a;
scanf ("%d%d",&x,&a);
update(1,1,n,dfn[x],ed[x],a);
}
if (fl==3)
{
int x;
scanf ("%d",&x);
printf("%lld\n",lca(x));
}
}
return 0;
}
我真是太愚蠢啦qaq