题意:给你一棵树,然后有三种操作

  I L R K: 把L与R的路径上的所有点权值加上K

  D L R K:把L与R的路径上的所有点权值减去K

  Q X:查询节点编号为X的权值

思路:树链剖分裸题(我还没有怎么学懂,但基本已经没有什么太大的问题,主要的问题就在于点或者边对于数据结构的映射关系是,主要没有单独手写过树链剖分,所以对这部分 没有什么体会)

我们知道树链剖分是一种将树剖为链的一种算法,其思想和dfs序差不多,但根据树链剖分的性质,我们的重链是连续的区间,这样对于重链或者重链上的点我们可以方便的用数据结构维护,对于修改操作,是一种类似于LCA的算法,但感觉本质上还是一种LCA,只不过每次向上跳的部分是跳到top,其他的就是两次dfs,分别维护组时候大小以及一些其他的东西,第二遍dfs 找出重链

代码:

#include <bits/stdc++.h>
using namespace std;const int maxn=50008;
const int maxm=100008;int n,m,Q;
int a[maxn],sz[maxn],dep[maxn],fa[maxn],top[maxn],w[maxn],son[maxn];
int Rank[maxn];
int sum[maxn<<2],lazy[maxn<<2];struct line
{int u,v,nxt;
}eg[maxm];
int head[maxn],summ,cnt;
void addedge(int u,int v)
{eg[++summ].u=u;eg[summ].v=v;eg[summ].nxt=head[u];head[u]=summ;
}
void add(int u,int v)
{addedge(u,v);addedge(v,u);
}
void dfs1(int u)
{sz[u]=1;son[u]=0;for(int i=head[u];i;i=eg[i].nxt){int v=eg[i].v;if(v!=fa[u]){fa[v]=u;dep[v]=dep[u]+1;dfs1(v);sz[u]+=sz[v];if(sz[v]>sz[son[u]])son[u]=v;}}
}void dfs2(int u,int tp,int x)
{top[u]=tp;w[u]=++cnt;Rank[cnt]=u;if(son[u])dfs2(son[u],tp,1);for(int i=head[u];i;i=eg[i].nxt){int v=eg[i].v;if(v==son[u]||v==fa[u])continue;dfs2(v,v,2);}
}void init()
{memset(head,0,sizeof(head));summ=1;cnt=0;dep[1]=1;fa[1]=0;
}
void pushup(int rt)
{sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int rt,int len)
{if(lazy[rt]){lazy[rt<<1]+=lazy[rt];lazy[rt<<1|1]+=lazy[rt];sum[rt<<1]+=lazy[rt]*(len-len/2);sum[rt<<1|1]+=lazy[rt]*(len/2);lazy[rt]=0;}
}void build(int l,int r,int rt)
{lazy[rt]=0;if(l==r){sum[rt]=a[Rank[l]];return ;}int mid=(l+r)>>1;build(l,mid,rt<<1);build(mid+1,r,rt<<1|1);pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt)
{if(L<=l&&r<=R){sum[rt]+=val*(r-l+1);lazy[rt]+=val;return ;}pushdown(rt,r-l+1);int mid=(l+r)>>1;if(L<=mid)update(L,R,val,l,mid,rt<<1);if(mid<R)update(L,R,val,mid+1,r,rt<<1|1);pushup(rt);
}int query(int x,int l,int r,int rt)
{if(l==r){return sum[rt];}pushdown(rt,r-l+1);int mid=(l+r)>>1;if(x<=mid)return query(x,l,mid,rt<<1);if(mid<x)return query(x,mid+1,r,rt<<1|1);
}
void modify(int x,int y,int val)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);update(w[top[x]],w[x],val,1,n,1);x=fa[top[x]];}if(dep[x]>dep[y])swap(x,y);update(w[x],w[y],val,1,n,1);
}int main()
{while(~scanf("%d%d%d",&n,&m,&Q)){init();for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);add(u,v);}dfs1(1);dfs2(1,1,1);build(1,cnt,1);while (Q--){char s[2];int x,y,z;scanf("%s",s);if (s[0]=='I'){scanf("%d %d %d",&x,&y,&z);modify(x,y,z);}if (s[0]=='D'){scanf("%d %d %d",&x,&y,&z);modify(x,y,-z);}if (s[0]=='Q'){scanf("%d",&x);printf("%d\n",query(w[x],1,n,1));}}}return 0;
}

转载于:https://www.cnblogs.com/lalalatianlalu/p/9740908.html

HDU 3966 Aragorn's Story (树链剖分+线段树)相关推荐

  1. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  2. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  3. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  4. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  5. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  6. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  7. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  8. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. Kendo Web UI Grid数据绑定,删除,编辑,并把默认英文改成中文
  2. etree.xpath获取数据为空的解决方法
  3. kali无限登录_Kali Linux没有无线网卡?玩个锤纸~
  4. C语言的math相关的函数
  5. 非对称卷积—Asymmetric Convolutions
  6. Python打印到文件
  7. bios升级工具_小白修电脑系列第十二期--手把手教你升级主板BIOS
  8. 《数据结构》陈越课件重点总结
  9. Processing的条件式
  10. php中文离线手册 chm_PHP官方中文手册2017最新完整版 带用户注释 chm
  11. JavaCV的摄像头实战之六:保存为mp4文件(有声音)
  12. 漫威超级英雄大全(一)
  13. smart bi 学习
  14. Shader学习7——法线贴图
  15. Python 基于sicpy求解定积分 ,不定积分以及多重积分
  16. MySQL 大量sleeping before entering InnoDB 故障诊断
  17. UDF函数和UDTF函数的图解举例,追加UDAF函数
  18. Python爬虫-Beautiful Soup-当当图书目录(1)
  19. el-table根据数据某个属性不同,做斑马纹,设置表格行样式
  20. 1024分辨率《X战警:第一战》BD中英双字无水印

热门文章

  1. Git本地仓库文件的创建、修改和删除
  2. debug=true开启自动配置报告
  3. mysql使用 CONCAT(字段,字段) 函数拼接
  4. Shell脚本案例:批量新增用户
  5. 12个 Linux 中 grep 命令的超级用法实例
  6. 9本Java程序员必读的书
  7. java的继承实例_Java继承和多态实例
  8. Android 第四课 活动的启动模式
  9. 6 个对所有 Web 开发者都有用的 GitHub 仓库
  10. 蛋花花APP,APP开发这几点你要注意了