【bzoj4034】[HAOI2015]树上操作(树链剖分+dfs序)
来源:互联网 发布:视频大数据分析 编辑:程序博客网 时间:2024/05/17 01:42
题目:
我是超链接
题解:
这题目比常识都要好想,dfs序维护子树
“常识”:1、bzoj看看范围要强转longlong 2、bzoj和洛谷支持lld输出….I64d挂了好多次【烦
代码:
#include <cstdio>#include <iostream>#define N 100000#define LL long long#define MIN -1e9using namespace std;int size[N*4],w[N*4],son[N*4],fa[N*4],deep[N*2+5];int top[N*4],in[N*4],out[N*4],tree[N*4];int nxt[N*2+5],point[N*2+5],v[N*2+5],tot=0,cnt=0,n;LL sum[N*4],delta[N*4+5];void addline(int x,int y){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; ++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;}void dfs_1(int now,int dep,int faa){ deep[now]=dep; size[now]=1; fa[now]=faa; int maxx=MIN; for (int i=point[now];i;i=nxt[i]) if (v[i]!=faa) { dfs_1(v[i],dep+1,now); size[now]+=size[v[i]]; if (size[v[i]]>maxx) { maxx=size[v[i]]; son[now]=v[i]; } }}void dfs_2(int now,int faa){ if (son[faa]!=now) top[now]=now; else top[now]=top[faa]; in[now]=++cnt; if (son[now]) { dfs_2(son[now],now); for (int i=point[now];i;i=nxt[i]) if (v[i]!=son[now] && v[i]!=faa) dfs_2(v[i],now); } out[now]=cnt;}void updata(int now){sum[now]=sum[now<<1]+sum[now<<1|1];}void pushdown(int now,int l,int r,int mid){ if (delta[now]) { delta[now<<1]+=delta[now]; delta[now<<1|1]+=delta[now]; sum[now<<1]+=delta[now]*(LL)(mid-l+1); sum[now<<1|1]+=delta[now]*(LL)(r-mid); delta[now]=0LL; }}void change1(int now,int l,int r,int x,int v){ if (l==r) { sum[now]+=(LL)v; return; } int mid=(l+r)>>1; pushdown(now,l,r,mid); if (x<=mid) change1(now<<1,l,mid,x,v); else change1(now<<1|1,mid+1,r,x,v); updata(now);}void change2(int now,int l,int r,int lrange,int rrange,int v){ if (lrange<=l && rrange>=r) { sum[now]+=(LL)v*(r-l+1); delta[now]+=(LL)v; return; } int mid=(l+r)>>1; pushdown(now,l,r,mid); if (mid>=lrange) change2(now<<1,l,mid,lrange,rrange,v); if (mid<rrange) change2(now<<1|1,mid+1,r,lrange,rrange,v); updata(now);}LL qurry(int now,int l,int r,int lrange,int rrange){ if (lrange<=l && rrange>=r) return sum[now]; int mid=(l+r)>>1;LL ans=0LL; pushdown(now,l,r,mid); if (mid>=lrange) ans+=qurry(now<<1,l,mid,lrange,rrange); if (mid<rrange) ans+=qurry(now<<1|1,mid+1,r,lrange,rrange); return ans; }void Q(int u,int v){ int f1=top[u],f2=top[v];LL summ=0LL; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } summ+=qurry(1,1,n,in[f1],in[u]); u=fa[f1]; f1=top[u]; } if (in[u]>in[v]) swap(u,v); summ+=qurry(1,1,n,in[u],in[v]); printf("%lld\n",summ);}void build(int now,int l,int r){ if (l==r) { sum[now]=(LL)w[tree[l]]; return; } int mid=(l+r)>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); updata(now);}int main(){ int m,i,x,y,id,vv; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&w[i]); for (i=1;i<=n-1;i++) { scanf("%d%d",&x,&y); addline(x,y); } dfs_1(1,1,0); dfs_2(1,0); for (i=1;i<=n;i++) tree[in[i]]=i; build(1,1,n); for (i=1;i<=m;i++) { scanf("%d",&id); switch (id) { case 1:scanf("%d%d",&x,&vv);change1(1,1,n,in[x],vv);break; case 2:scanf("%d%d",&x,&vv);change2(1,1,n,in[x],out[x],vv);break; case 3:scanf("%d",&x);Q(1,x);break; } }}
1 0
- 【bzoj4034】[HAOI2015]树上操作(树链剖分+dfs序)
- 【树链剖分(DFS序)+线段树】BZOJ4034(HAOI2015)[树上操作]题解
- [BZOJ4034][HAOI2015]树上操作(链剖+dfs序)
- 【BZOJ4034】树上操作(HAOI2015)-树链剖分
- 【bzoj4034】【HAOI2015】【树上操作】【树链剖分】
- bzoj4034 [HAOI2015]树上操作(树链剖分)
- 【树链剖分】bzoj4034: [HAOI2015]树上操作
- [bzoj4034][HAOI2015]树上操作 dfs序+树状数组
- BZOJ4034(HAOI2015)[树上操作]--线段树+DFS序
- bzoj4034 [HAOI2015]树上操作
- 【bzoj4034】[HAOI2015]树上操作
- BZOJ4034: [HAOI2015]树上操作
- [bzoj4034][HAOI2015]树上操作
- bzoj4034: [HAOI2015]树上操作
- 【BZOJ4034】【HAOI2015】树上操作
- bzoj4034 [HAOI2015]树上操作
- bzoj4034: [HAOI2015]树上操作
- BZOJ4034 [HAOI2015]树上操作
- qAdmin cannot perform this operation on a closed dataset
- 团体程序设计天梯赛-练习集 L2-016. 愿天下有情人都是失散多年的兄妹 解题报告
- oracle数据库技术____数据库的安装linux
- java编程题:50个人围成一圈数到3和3的倍数时出圈,问剩下的人是谁,在原来的位置是多少?
- yum 不能正常使用
- 【bzoj4034】[HAOI2015]树上操作(树链剖分+dfs序)
- h5c3内容04
- 2017GMTC全球移动技术大会——“11大顶级主题专场”
- Git:代码冲突常见解决方法
- 算法17:实现memcpy(void *src, int size, void *dest)
- spring ModelAttribute
- jQuery中ready与load事件的区别
- SurfaceView 画笔随机颜色满天星
- TortoiseSVN与VisualSVN Server搭建SVN版本控制系统