hdu 3966 Aragorn's Story 树链剖分
来源:互联网 发布:网络威胁别人什么罪 编辑:程序博客网 时间:2024/05/16 17:43
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966
题意:
给定一棵树,且给定这棵树上各个点的权值,有以下三种操作:I x y z:将点x到点y的路径上的所有点加上z;D x y z:将点x到点y的路径上的所有点减去z;Q x:查询点x的权值。
树链剖分裸题,先剖分后用线段树维护。
手动开栈!手动开栈!手动开栈!
#pragma comment(linker, "/STACK:1024000000,1024000000")
关于树链剖分,我认为它是将一棵树,按照重边分成了一堆的链,之后将这些链首尾相连,之后就用各种数据结构去搞一搞就可以了。
Code
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 50010#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;struct node{ int next,to;};node Edge[N<<1];int n,m,q,tot,QT;int a[N];int dfn[N],son[N],fa[N],size[N];int w[N],top[N];int pp[N];int f[N<<2],sum[N<<2];int head[N];void clear(){ memset(head,0,sizeof(head)); memset(son,0,sizeof(son)); memset(dfn,0,sizeof(dfn)); memset(fa,0,sizeof(fa)); memset(size,0,sizeof(size)); memset(w,0,sizeof(w)); memset(top,0,sizeof(top)); memset(pp,0,sizeof(pp)); tot=0; QT=0;}void addedge(int x,int y){ Edge[++tot].next=head[x]; Edge[tot].to=y; head[x]=tot;}void dfs1(int u,int root,int deep){ fa[u]=root; dfn[u]=deep; size[u]=1; for(int i=head[u];i;i=Edge[i].next) { int to=Edge[i].to; if(to==root)continue; dfs1(to,u,deep+1); size[u]+=size[to]; if(size[to]>size[son[u]])son[u]=to; }}void dfs2(int u,int tp){ top[u]=tp; w[u]=++QT; pp[QT]=u; if(!son[u])return ; dfs2(son[u],tp); for(int i=head[u];i;i=Edge[i].next) { int to=Edge[i].to; if(to==fa[u]||to==son[u])continue; dfs2(to,to); }}void PushUp(int rt){ f[rt]=max(f[rt<<1],f[rt<<1|1]);}void PushDown(int rt){ if(!sum[rt])return ; sum[rt<<1]+=sum[rt]; sum[rt<<1|1]+=sum[rt]; f[rt<<1]+=sum[rt]; f[rt<<1|1]+=sum[rt]; sum[rt]=0;}void build(int l,int r,int rt){ sum[rt]=0; if(l==r) { f[rt]=a[pp[l]]; return ; } int mid=(l+r)>>1; build(lson); build(rson); PushUp(rt);}int query(int l,int r,int rt,int x){ if(l==r)return f[rt]; PushDown(rt); int mid=(l+r)>>1; int ans=0; if(mid>=x)ans=query(lson,x); else ans=query(rson,x); PushUp(rt); return ans;}void updata(int l,int r,int rt,int L,int R,int c){ if(l>=L&&r<=R) { f[rt]+=c; sum[rt]+=c; return ; } PushDown(rt); int mid=(l+r)>>1; if(mid>=L)updata(lson,L,R,c); if(mid<R) updata(rson,L,R,c); PushUp(rt);}void change(int x,int y,int cnt){ while(top[x]!=top[y]) { if(dfn[top[x]]<dfn[top[y]])swap(x,y); updata(1,n,1,w[top[x]],w[x],cnt); x=fa[top[x]]; } if(dfn[x]>dfn[y])swap(x,y); updata(1,n,1,w[x],w[y],cnt);}int main(){ while(~scanf("%d%d%d",&n,&m,&q)) { clear(); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } dfs1(1,0,1); dfs2(1,1); build(1,n,1); for(int i=1;i<=q;i++) { char s[10]; int x,y,z; scanf("%s",s); if(s[0]=='Q') { scanf("%d",&x); printf("%d\n",query(1,n,1,w[x])); }else { scanf("%d%d%d",&x,&y,&z); if(s[0]=='D')z=-z; change(x,y,z); } } } return 0;}
0 0
- HDU 3966 Aragorn's Story 树链剖分模板
- hdu 3966 Aragorn's Story(树链剖分)
- hdu 3966 Aragorn's Story (树链剖分)
- hdu 3966 Aragorn's Story 树链剖分
- Hdu 3966 Aragorn's Story (树链剖分)
- 【HDU】3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story(树链剖分)
- hdu 3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story --树链剖分
- HDU 3966 Aragorn's Story (树链剖分)
- HDU 3966 Aragorn's Story(树链剖分)
- [HDU 3966] Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story(树链剖分)
- HDU 3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story(树链剖分)
- HDU 3966 Aragorn's Story(树链剖分)
- HDU 3966 - Aragorn's Story(树链剖分)
- 解决聊天输入框一直跳动的bug
- Ubuntu VirtualBox 命令行安装
- 162.Oracle数据库SQL开发之 SQL优化——优化器传递提示
- Lenovo笔记本各类型触控板,触摸部分只能移动无法点击的问题汇总
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭
- hdu 3966 Aragorn's Story 树链剖分
- nginx 源码学习笔记(十一)——基本容器——ngx_list
- 163.Oracle数据库SQL开发之 SQL优化——优化工具
- 提示框第三方库之MBProgressHUD iOS toast效果 动态提示框效果
- 实际开发注意的问题
- CentOS-7安装配置JDK-7
- libEvent 使用
- nginx 源码学习笔记(十二)——基本容器——ngx_buf
- 164.Oracle数据库SQL开发之 XML和ORACLE——XML简介