图论之树链剖分模板
来源:互联网 发布:sql注入 预处理 编辑:程序博客网 时间:2024/06/05 03:00
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define MEM(a,b) memset(a,b,sizeof(a));int n,m,s;const int maxn=100010;struct Node{ int u,v,w,next;}e[maxn],edge[2*maxn];int cnt;int head[maxn];//记siz[v]表示以v为根的子树的节点数,dep[v]表示v的深度(根深度为1),top[v]表示v所在的链的//顶端节点,fa[v]表示v的父亲,son[v]表示与v在同一重链上的v的儿子节点(姑且称为重儿子),//id[v]表示v与其父亲节点的连边(姑且称为v的父边)在线段树中的位置。int dep[maxn],siz[maxn],son[maxn],fa[maxn];int top[maxn],id[maxn];////top 最近的重链父节点int num;void addedge(int u,int v){ edge[cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u]++;head[u]=cnt++;}void dfs1(int u,int f,int d){ dep[u]=d; siz[u]=1; son[u]=0; fa[u]=f; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==f)continue; dfs1(v,u,d+1); siz[u]+=siz[v]; if(siz[son[u]]<siz[v]) son[u]=v; }}void dfs2(int u,int tp){ top[u]=tp; id[u]=++num; if(son[u])dfs2(son[u],tp); for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa[u]||v==son[u])continue; dfs2(v,v); }}struct Tree{ int l,r,val;}tree[4*maxn];#define lson 2*o,l,mid#define rson 2*o+1,mid+1,rint Val[maxn];void pushup(int x){ tree[x].val=tree[2*x].val+tree[2*x+1].val;}void build(int o,int l,int r){//建树一致 tree[o].l=l;tree[o].r=r; if(l==r){ tree[o].val=Val[l]; return; } int mid=(l+r)>>1; build(lson); build(rson); pushup(o);}void update(int o,int a,int b){//更新操作一致 if(tree[o].l==tree[o].r){ tree[o].val=b; return; } int mid=(tree[o].l+tree[o].r)>>1; if(a<=mid) update(2*o,a,b); else update(2*o+1,a,b); pushup(o);}int query(int o,int l,int r){ if(tree[o].l>=l&&tree[o].r<=r){ return tree[o].val; } int mid=(tree[o].l+tree[o].r)>>1; if(r<=mid) return query(2*o,l,r); else if(l>mid) return query(2*o+1,l,r); else return query(lson)+query(rson);}int find(int u,int v){ int tp1=top[u],tp2=top[v]; int ans=0; while(tp1!=tp2){ if(dep[tp1]<dep[tp2]){ swap(tp1,tp2); swap(u,v); } ans+=query(1,id[tp1],id[u]); u=fa[tp1]; tp1=top[u]; } if(u==v)return ans; if(dep[u]>dep[v])swap(u,v); ans+=query(1,id[son[u]],id[v]); return ans;}int main(){ scanf("%d%d%d",&n,&m,&s); cnt=0;num=0; MEM(head,-1); for(int i=1;i<n;i++){ scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); addedge(e[i].u,e[i].v); addedge(e[i].v,e[i].u); } dfs1(1,0,1); dfs2(1,1); for(int i=1;i<n;i++){ if(dep[e[i].u]<dep[e[i].v]) std::swap(e[i].u,e[i].v); Val[id[e[i].u]]=e[i].w; } build(1,1,num); for(int i=0;i<m;i++){ int ok,x,y; scanf("%d",&ok); if(ok==0){ scanf("%d",&x); printf("%d\n",find(s,x)); s=x; } else{ scanf("%d%d",&x,&y); update(1,id[e[x].u],y); } } return 0;}
0 0
- 图论之树链剖分模板
- 模板之图论
- 图论之2-sat模板
- 图论之离线lca模板
- LCA之树链剖分(模板)
- 模板之函数模板
- 模板之---类模板
- 模板之函数模板
- LCA之树链剖分 zhn_666的lca 模板
- C++模板之函数模板
- c++ 模板之函数模板
- c++模板之函数模板
- C++模板之函数模板
- c++学习之模板模板
- 数据结构之图——模板实现
- 图论模板
- 图论模板
- 图论模板
- 图论之离线lca模板
- java基础知识—String、StringBuffer和StringBuilder
- 教你在Android Studio 中进行单元测试
- nginx+lua+redis搭建
- 深度学习在图像识别中的应用--学习笔记3
- 图论之树链剖分模板
- Android_运用log4j打印日志
- 【Maven】Maven解决Maven Repository 没有
- (算法入门)基本图论-深度优先搜索之JAVA实现
- 引用计数
- Java子类继承(二):隐藏成员变量和方法重写的理解
- python RSA签名和解签
- 关于html选择文件(input指定类型js判断)
- 黑马程序员_反射