您的位置:首页 > 其它

4034: [HAOI2015]T2 树链剖分+线段树

2016-01-20 07:13 316 查看
卧槽一开始建的单向边结果T的停不下来。

傻逼链剖,别人家的省选qwq。

#include<iostream>
#include<cstdio>
#define N 100005
#define ll long long
using namespace std;
int n,m,cnt,dfn,v
,head
,size
,deep
,fa
,in
,out
,belong
;
int list[N<<1],next[N<<1];
int l[N<<2],r[N<<2];
ll sum[N<<2],tag[N<<2];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
void dfs1(int x)
{
size[x]=1;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa[x])
{
fa[list[i]]=x;
deep[list[i]]=deep[x]+1;
dfs1(list[i]);
size[x]+=size[list[i]];
}
}
void dfs2(int x,int chain)
{
in[x]=++dfn; belong[x]=chain;
int k=0;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa[x]&&size[list[i]]>size[k]) k=list[i];
if (!k) {out[x]=dfn; return;}
dfs2(k,chain);
for (int i=head[x];i;i=next[i])
if (list[i]!=fa[x]&&list[i]!=k) dfs2(list[i],list[i]);
out[x]=dfn;
}
inline void pushup(int k)
{
sum[k]=sum[k<<1]+sum[k<<1|1];
}
inline void pushdown(int k)
{
if (l[k]==r[k]||tag[k]==0) return;
tag[k<<1]+=tag[k]; tag[k<<1|1]+=tag[k];
sum[k<<1]+=tag[k]*(r[k<<1]-l[k<<1]+1);
sum[k<<1|1]+=tag[k]*(r[k<<1|1]-l[k<<1|1]+1);
tag[k]=0;
}
void build(int k,int x,int y)
{
l[k]=x; r[k]=y;
if (l[k]==r[k]) return;
int mid=l[k]+r[k]>>1;
build(k<<1,x,mid); build(k<<1|1,mid+1,y);
pushup(k);
}
void modify(int k,int x,int y,ll val)
{
pushdown(k);
if (l[k]==x&&r[k]==y)
{
sum[k]+=(ll)(r[k]-l[k]+1)*val;
tag[k]+=val;
return;
}
int mid=l[k]+r[k]>>1;
if (y<=mid) modify(k<<1,x,y,val);
else if (x>mid) modify(k<<1|1,x,y,val);
else modify(k<<1,x,mid,val),modify(k<<1|1,mid+1,y,val);
pushup(k);
}
ll query(int k,int x,int y)
{
pushdown(k);
if (l[k]==x&&r[k]==y) return sum[k];
int mid=l[k]+r[k]>>1;
if (y<=mid) return query(k<<1,x,y);
else if (x>mid) return query(k<<1|1,x,y);
else return query(k<<1,x,mid)+query(k<<1|1,mid+1,y);
}
inline ll solve_query(int x)
{
ll ans=0;
while (belong[x]!=1)
{
ans+=query(1,in[belong[x]],in[x]);
x=fa[belong[x]];
}
ans+=query(1,1,in[x]);
return ans;
}
int main()
{
n=read(); m=read();
for (int i=1;i<=n;i++) v[i]=read();
for (int i=1;i<n;i++)
{
int u=read(),v=read();
insert(u,v); insert(v,u);
}
dfs1(1);
dfs2(1,1);
build(1,1,n);
for (int i=1;i<=n;i++) modify(1,in[i],in[i],v[i]);
for (int i=1;i<=m;i++)
{
int opt=read(),x=read(),a;
switch (opt)
{
case 1:
a=read();
modify(1,in[x],in[x],a);
break;
case 2:
a=read();
modify(1,in[x],out[x],a);
break;
case 3:
printf("%lld\n",solve_query(x));
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: