bzoj4034: [HAOI2015]T2
4034: [HAOI2015]T2
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 2684 Solved: 843
Description
有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
Input
第一行包含两个整数 N, M 。表示点数和操作数。
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
Sample Input
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
9
13
HINT
对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不
Source
1554438
| ksq2013 | 4034 | Accepted | 15676 kb | 2760 ms | C++/Edit | 2537 B | 2016-07-18 19:59:13 |
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
int n,q,first[100100],val[100100];
ll col[400100],sum[400100];
struct Edge{int u,v,nxt;Edge(){nxt=0;}}e[200100];
int cnt,sz[100100],id[100100],mx[100100],fa[100100],blg[100100];
void dfs1(int x)
{
sz[x]=1;
for(int i=first[x];i;i=e[i].nxt)
if(e[i].v!=fa[x]){
fa[e[i].v]=x;
dfs1(e[i].v);
sz[x]+=sz[e[i].v];
}
}
void dfs2(int x,int tp)
{
blg[x]=tp;
id[x]=mx[x]=++cnt;
int k=0;
for(int i=first[x];i;i=e[i].nxt)
if(e[i].v!=fa[x]&&sz[e[i].v]>sz[k])
k=e[i].v;
if(k){
dfs2(k,tp);
mx[x]=max(mx[x],mx[k]);
}
for(int i=first[x];i;i=e[i].nxt)
if(e[i].v!=fa[x]&&e[i].v!=k)
{dfs2(e[i].v,e[i].v);mx[x]=max(mx[x],mx[e[i].v]);}
}
inline void pushdown(int k,int m)
{
if(col[k]){
col[k<<1]+=col[k];
col[k<<1|1]+=col[k];
sum[k<<1]+=(m-(m>>1))*col[k];
sum[k<<1|1]+=(m>>1)*col[k];
col[k]=0;
}
}
void update(int s,int t,int k,int l,int r,ll p)
{
if(l<=s&&t<=r){
sum[k]+=p*(ll)(t-s+1);
col[k]+=p;
return;
}pushdown(k,t-s+1);
int m=(s+t)>>1;
if(l<=m)update(s,m,k<<1,l,r,p);
if(r>m)update(m+1,t,k<<1|1,l,r,p);
sum[k]=sum[k<<1]+sum[k<<1|1];
}
ll qsum(int s,int t,int k,int l,int r)
{
if(l<=s&&t<=r)return sum[k];
pushdown(k,t-s+1);
int m=(s+t)>>1;
ll res=0;
if(l<=m)res+=qsum(s,m,k<<1,l,r);
if(r>m)res+=qsum(m+1,t,k<<1|1,l,r);
return res;
}
ll solvesum(int x,int f)
{
ll res=0;
while(blg[x]!=blg[f]){
res+=qsum(1,n,1,id[blg[x]],id[x]);
x=fa[blg[x]];
}
res+=qsum(1,n,1,id[f],id[x]);
return res;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
for(int i=1;i<=n-1;i++){
scanf("%d%d",&e[i].u,&e[i].v);
e[i].nxt=first[e[i].u];
first[e[i].u]=i;
e[i+n-1].u=e[i].v;
e[i+n-1].v=e[i].u;
e[i+n-1].nxt=first[e[i].v];
first[e[i].v]=i+n-1;
}
dfs1(1);
dfs2(1,1);
for(int i=1;i<=n;i++)
update(1,n,1,id[i],id[i],val[i]);
for(int i=1;i<=q;i++){
int d,x,y;
scanf("%d",&d);
switch(d){
case 1:scanf("%d%d",&x,&y);update(1,n,1,id[x],id[x],y);break;
case 2:scanf("%d%d",&x,&y);update(1,n,1,id[x],mx[x],y);break;
case 3:scanf("%d",&x);printf("%lld\n",solvesum(x,1));break;
}
}
return 0;
}
bzoj4034: [HAOI2015]T2的更多相关文章
- BZOJ4034——[HAOI2015]T2
1.题目大意:用一个数据结构支持树的点修改和子树修改.树上路径和 2.分析:树链剖分裸题 #include <cstdio> #include <cstdlib> #inclu ...
- [BZOJ4034] [HAOI2015] T2 (树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...
- 【DFS序】【线段树】bzoj4034 [HAOI2015]T2
分开维护树的入栈序和出栈序,用两棵线段树.回答时就是用一颗的减去另一棵的. #include<cstdio> #include<algorithm> using namespa ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1841 Solved: 598[Submit][Status] ...
- BZOJ 4034: [HAOI2015]T2( 树链剖分 )
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...
- bzoj 4034: [HAOI2015]T2
4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...
- 【bzoj4034】[HAOI2015]T2
siz[v]表示以v为根的子树的节点数 top[v]表示v所在的重链的顶端节点 fa[v]表示v的父亲 pos[v]表示v的父边标号 mx[v]表示v的子树中边的标号最大的那条边 参考:http:// ...
- 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
随机推荐
- 微信小程序(应用号)开发资源汇总整理 - 一直更新中
开源项目 wechat-weapp-gank - 微信小程序版Gank客户端 wechat-dribbble - 微信小程序-Dribbble wechatApp-demo - 微信小程序 DEMO ...
- 遍历collection
链接 遍历NSArray 正向遍历 for (id object in array) 反向遍历 for (id object in [array reverseObjectEnumerator]) 如 ...
- Unable to execute dex: Multiple dex files define(错误分析)
eclipse工程包名与依靠的代码库包名不能冲突,否则运行程序程序会出错 错误提示:
- 【数据库】MySQL的安装与简单使用
首先我们要下载Mysql的安装包,大家可以到http://mysql.com官网中根据自己的电脑系统版本下载 也可以点击 MySQL资源 下载 密码:btuu 建议下载5.7以上的版本,因为省掉了许多 ...
- C++语言-09-多任务
概述 概念 计算机同时运行多个程序的能力,多任务处理的方法是:运行第一个程序的一段代码,保存工作环境:再运行第二个程序的一段代码,保存工作环境:--恢复第一个程序的工作环境,执行第一个程序的下一段代码 ...
- Oracle与MySQL的区别
1. Oracle是大型数据库而Mysql是中小型数据库,Oracle市场占有率达40%,Mysql只有20%左右,同时Mysql是开源的而Oracle价格非常高. 2. Oracle支持大并发,大访 ...
- nodejs API
1.querystring参数处理 序列化 > querystring.stringify({'name':'scott',course:['jade','node'],from:''}) 'n ...
- FTP远程文件传输命令
使用ftp命令进行远程文件传输 ftp命令是标准的文件传输协议的用户接口.ftp是在TCP/IP网络上的计算机之间传输文件的简单有效的方法.它允许用户传输ASCII文件和二进制文件. 在ftp会话过程 ...
- 深入理解Angular中的$Apply()以及$Digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- Java数组的12个常用方法
以下是12个关于Java数组最常用的方法,它们是stackoverflow得票最高的问题. 声明一个数组 String[] aArray = new String[5]; String[] bArra ...