BZOJ4034 [HAOI2015]T2 题解&代码
来源:互联网 发布:减肥从130到90 知乎 编辑:程序博客网 时间:2024/06/11 22:51
题意: 有一棵有N个节点的树,以节点1为根,且点上有权。
有M个操作,分为三种:
操作 1 把节点x的点权增加 a
操作 2 把以节点x为根的树中所有点的点权都增加a
操作 3 求节点x到根的路径中所有点的点权和
分析:
操作1和操作2本质上是没有区别的,区间修改和单点修改显然可以合并,求dfs序后线段树区间维护就可以了
操作3是涉及路径的查询,和树剖很类似,但是比树剖简单很多【比如我求的deep完全没有用2333333】,按照树剖的思路分段查询即可
note:
线段树八倍空间!不然会迷之RE!明明四倍理论上是可以的QAQ
最开始初始化忘记初始化size[]了…于是各种算错233333我个智障
/************************************************************** Problem: 4034 User: Rainbow6174 Language: C++ Result: Accepted Time:3920 ms Memory:29872 kb****************************************************************/#include<iostream>#include<vector>#include<cstdio>#define lson (o<<1)#define rson ((o<<1)|1)#define LL long longusing namespace std;const int maxn = 100005;vector<int> edge[maxn];int n,m,op,x,tot,val[maxn],in[maxn],out[maxn],deep[maxn],son[maxn],fa[maxn],rt[maxn],fin[maxn];LL sum[8*maxn],lazy[8*maxn],size[8*maxn];void dfs1(int x,int pre){ fa[x] = pre; son[x] = -1; size[x] = 1; deep[x] = deep[pre]+1; for(int i = 0; i < edge[x].size(); i++) if(edge[x][i] != pre) { dfs1(edge[x][i],x); size[x] += size[edge[x][i]]; if(son[x]==-1 || size[edge[x][i]]>size[son[x]]) son[x] = edge[x][i]; }}void dfs2(int x,int root){ rt[x] = root; in[x] = out[x] = ++tot; fin[in[x]] = x; if(son[x] != -1)dfs2(son[x],root); for(int i = 0; i < edge[x].size(); i++) if(edge[x][i] != fa[x] && edge[x][i] != son[x]) dfs2(edge[x][i],edge[x][i]); out[x]=tot;}void maintain(int o,int l,int r){ if(l!=r)sum[o]=sum[lson]+sum[rson];}void pushdown(int o,int l,int r){ if(lazy[o]) { sum[lson]+=size[lson]*lazy[o]; sum[rson]+=size[rson]*lazy[o]; lazy[lson]+=lazy[o]; lazy[rson]+=lazy[o]; } lazy[o]=0;}void build(int o,int l,int r){ if(l==r) { sum[o]=(LL)val[fin[l]]; size[o]=1; //cout<<o<<' '<<sum[o]<<endl; return; } int mid = (l+r)/2; build(lson,l,mid); build(rson,mid+1,r); maintain(o,l,r); size[o]=size[lson]+size[rson];}void addtree(int o,int l,int r,int L,int R,int v){ pushdown(o,l,r); if(R<l || L>r)return; if(l>=L && r<=R) { lazy[o]+=(LL)v; sum[o]+=((LL)size[o])*((LL)v); //cout<<"test "<<o<<' '<<l<<' '<<r<<' '<<sum[o]<<endl; return; } int mid=(l+r)>>1; addtree(lson,l,mid,L,R,v); addtree(rson,mid+1,r,L,R,v); maintain(o,l,r);}LL query(int o,int l,int r,int L,int R){ pushdown(o,l,r); if(R<l || L>r)return 0; if(l>=L && r<=R)return sum[o]; int mid=(l+r)>>1; return query(lson,l,mid,L,R)+query(rson,mid+1,r,L,R);}LL Query(int x){ LL ret = 0; while(rt[x]!=1) { ret+=query(1,1,n,in[rt[x]],in[x]); x=fa[rt[x]]; } ret+=query(1,1,n,1,in[x]); return ret;}int main(void){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) scanf("%d",&val[i]),sum[i]=i; int u,v; for(int i = 1; i < n; i++) { scanf("%d%d",&u,&v); edge[u].push_back(v); edge[v].push_back(u); } dfs1(1,0);dfs2(1,1); build(1,1,n); for(int i = 0; i < m; i++) { scanf("%d%d",&op,&x); if(op==1) { scanf("%d",&v); addtree(1,1,n,in[x],in[x],v); } if(op==2) { scanf("%d",&v); addtree(1,1,n,in[x],out[x],v); } if(op==3)printf("%lld\n",Query(x)); } return 0;}
1 0
- BZOJ4034 [HAOI2015]T2 题解&代码
- [BZOJ4034][HAOI2015]T2
- bzoj4034: [HAOI2015]T2
- [BZOJ4034] [HAOI2015]T2
- bzoj4034[HAOI2015]T2 - 树链剖分
- BZOJ4034:[HAOI2015]T2
- bzoj4034: [HAOI2015]T2
- Bzoj4034:[HAOI2015]T2:树链剖分
- bzoj4034: [HAOI2015]T2
- [BZOJ4034] [HAOI2015] T2 - 树链剖分
- bzoj4034 HAOI2015 T2 树链剖分
- 【bzoj4034】[HAOI2015]T2
- bzoj4034: [HAOI2015]T2
- 【bzoj4034】[HAOI2015]T2
- 【HAOI2015】【BZOJ4034】树上操作T2
- [题解]bzoj4034 HAOI2015 树上操作
- 【bzoj4034】 HAOI2015 T2 树链剖分+小变形
- [BZOJ4034][HAOI2015]T2 做题笔记
- 基于R语言的模型组合
- Centos 6,7 YUM本地源,网络源
- spring ioc原理
- Django Model实例
- XListView上拉加载下拉刷新
- BZOJ4034 [HAOI2015]T2 题解&代码
- 1009 说反话
- mybatis in的使用问题
- Android 控件绑定事件的几种方法
- JSON与XML的区别比较
- java--容器
- 工厂方法模式
- 关于ubuntu14.04下开启wifi给Android使用的方法
- Spring MVC Controller默认是单例