4034: [HAOI2015]T2

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1841  Solved: 598
[Submit][Status][Discuss]

Description

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个

操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
 

Input

第一行包含两个整数 N, M 。表示点数和操作数。

接下来一行 N 个整数,表示树中节点的初始权值。
接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。
 

Output

对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

 

Sample Input

5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3

Sample Output

6
9
13

HINT

对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不

会超过 10^6 。

Source

鸣谢bhiaibogf提供

题解:

直接树链剖分。

还有处理一下子树即可。(dfs序)。

 #include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define LL long long
struct node
{
int begin,end,next;
}edge[*MAXN];
struct NODE
{
int left,right;
LL sum,add;
}tree[*MAXN];
int cnt,Head[MAXN],a[MAXN],size[MAXN],deep[MAXN],n,P[MAXN][],pos[MAXN],belong[MAXN],ks[MAXN],js[MAXN],SIZE;
bool vis[MAXN];
void addedge(int bb,int ee)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee)
{
addedge(bb,ee);addedge(ee,bb);
}
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
void dfs1(int u)
{
int i,v;
size[u]=;vis[u]=true;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(vis[v]==false)
{
deep[v]=deep[u]+;
P[v][]=u;
dfs1(v);
size[u]+=size[v];
}
}
}
void Ycl()
{
int i,j;
for(j=;(<<j)<=n;j++)
{
for(i=;i<=n;i++)
{
if(P[i][j-]!=-)P[i][j]=P[P[i][j-]][j-];
}
}
}
void dfs2(int u,int chain)
{
int k=,i,v;
pos[u]=++SIZE;belong[u]=chain;ks[u]=SIZE;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(deep[v]>deep[u]&&size[v]>size[k])k=v;
}
if(k==){js[u]=SIZE;return;}
dfs2(k,chain);
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
}
js[u]=SIZE;
}
void Pushup(int k)
{
tree[k].sum=tree[k*].sum+tree[k*+].sum;
}
void Build(int k,int l,int r)
{
tree[k].left=l;tree[k].right=r;tree[k].add=;
if(l==r)return;//{tree[k].sum=a[l];return;}
int mid=(l+r)/;
Build(k*,l,mid);Build(k*+,mid+,r);
//Pushup(k);
}
/*void Pushup(int k)
{
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}*/
void Pushdown(int k)
{
int l=k*,r=k*+,mid;
if(tree[k].add!=)
{
mid=(tree[k].left+tree[k].right)/;
tree[l].sum+=(LL)(mid-tree[k].left+)*tree[k].add;
tree[r].sum+=(LL)(tree[k].right-mid)*tree[k].add;
tree[l].add+=tree[k].add;
tree[r].add+=tree[k].add;
tree[k].add=;
}
}
void Add(int k,int l,int r,int A)
{
if(l<=tree[k].left&&tree[k].right<=r){tree[k].add+=(LL)A;tree[k].sum+=(LL)(tree[k].right-tree[k].left+)*A;return;}
Pushdown(k);
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)Add(k*,l,r,A);
else if(l>mid)Add(k*+,l,r,A);
else {Add(k*,l,mid,A);Add(k*+,mid+,r,A);}
Pushup(k);
}
LL Query_sum(int k,int l,int r)
{
if(l<=tree[k].left&&tree[k].right<=r)return (LL)tree[k].sum;
Pushdown(k);
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)return Query_sum(k*,l,r);
else if(l>mid)return Query_sum(k*+,l,r);
else return Query_sum(k*,l,mid)+Query_sum(k*+,mid+,r);
//Pushup(k);
}
LL Solve_sum(int x,int f)
{
LL sum=;
while(belong[x]!=belong[f])
{
sum+=Query_sum(,pos[belong[x]],pos[x]);
x=P[belong[x]][];
}
sum+=Query_sum(,pos[f],pos[x]);
return sum;
}
int main()
{
int m,i,bb,ee,zs,k,k1;
n=read();m=read();
for(i=;i<=n;i++)a[i]=read();
memset(Head,-,sizeof(Head));cnt=;
for(i=;i<n;i++)
{
bb=read();ee=read();
addedge1(bb,ee);
}
memset(P,-,sizeof(P));SIZE=;
dfs1();Ycl();
dfs2(,);
Build(,,n);
for(i=;i<=n;i++)Add(,pos[i],pos[i],a[i]);
for(i=;i<=m;i++)
{
zs=read();
if(zs==)
{
k=read();k1=read();Add(,pos[k],pos[k],k1);
}
else if(zs==)
{
k=read();k1=read();Add(,ks[k],js[k],k1);
}
else
{
k=read();printf("%lld\n",Solve_sum(k,));
}
}
return ;
}

Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序的更多相关文章

  1. BZOJ 4034: [HAOI2015]T2( 树链剖分 )

    树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...

  2. [BZOJ4034] [HAOI2015] T2 (树链剖分)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...

  3. 【树链剖分】【dfs序】【线段树】bzoj2836 魔法树

    这道题告诉我们:树链剖分的重标号就是dfs序. #include<cstdio> #include<algorithm> using namespace std; #defin ...

  4. JZYZOJ1539[haoi2015]T2 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...

  5. 【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

    一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树……但是会TLE. LCT一样无脑,但是少 ...

  6. 【bzoj4771】七彩树 树链的并+STL-set+DFS序+可持久化线段树

    题目描述 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义 ...

  7. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  8. BZOJ 4034 [HAOI2015]T2(树链剖分)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...

  9. bzoj 4034: [HAOI2015]T2

    4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...

随机推荐

  1. 理解Java中的字符串类型

    1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和w ...

  2. ubuntu zendDebugger.so 加载不上的问题

    参考文章   http://blog.sina.com.cn/s/blog_6612d5810101dapf.html 装zenDdebugger是为了在eclipse中调试用!!!!!!!结果搞了半 ...

  3. leetcode problem 31 -- Next Permutation

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  4. Fedora 21 安装QQ国际版

    首先安装依赖包 sudo yum install freetype.i686 libpng.i686 libgcc.i686 libXau.i686 点击下载wine-2012qq国际版 unzip ...

  5. 常用js函数

    1.获得元素到页面的绝对距离 function getPos(obj) { var pos = {left:0, top:0}; while (obj) { pos.left += obj.offse ...

  6. @using (Html.BeginForm())收集

    一 ,制定表单提交方式和路径 1,指明(视图,控制器,提交方式,参数) <%using(Html.BeginForm("Index","Home",For ...

  7. 列表字体css

    white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; overflow: hidden;

  8. 翻译:ECMAScript 5.1简介

    简介 ECMAScript 5.1 (或仅 ES5) 是ECMAScript(基于JavaScript的规范)标准最新修正. 与HTML5规范进程本质类似,ES5通过对现有JavaScript方法添加 ...

  9. HTTP状态码——对照表

    ASCII码介绍: HTTP状态码(HTTP Status Code)用来表示web服务器响应客户端的HTTP状态.主要有一下5种状态类型.1xx    消息2xx    成功3xx    重定向4x ...

  10. ruby Methods, Procs, Lambdas, and Closures

    define simple method定义简单方法 关键字def用于方法定义,在其后是方法名和可选的参数名列表,参数名列表会用一对圆括号括住.构成方法主体的代码放在参数列表之后,end用于结束方法定 ...