近期在强化知识点深度。发现树链剖分不是非常会写了。

回想一下改动操作:

若两个点在同一条链上,则直接改动这段区间。

若不在同一条链上,改动深度较大的点到其链顶端的区间,同一时候将这个点变为他所在链顶端的父亲,循环操作直到这两个点在同一条链上。就能够用上一种方法了。

没实用LCA写是由于曾经被坑过,不但没有这样的方法好写。效率也不太让人惬意。

主要是对另外一种情况怎样写有所遗忘。写道模版再给自己提个醒。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 50005
int n,m,q;
vector<int> map[MAXN];
int size[MAXN],fa[MAXN],son[MAXN],val[MAXN],tid[MAXN],_tid[MAXN],dep[MAXN],top[MAXN];
int cnt;
struct node
{
int l,r,val;
}tree[MAXN<<2];
void dfs1(int s,int f,int d)
{
size[s]=1;
fa[s]=f;
dep[s]=d;
int len=map[s].size();
for(int i=0;i<len;i++)
{
int e=map[s][i];
if(e==f)continue;
dfs1(e,s,d+1);
size[s]+=size[e];
if(son[s]==0)
son[s]=e;
else if(size[son[s]]<size[e])
son[s]=e;
}
}
void dfs2(int s,int t)
{
tid[s]=++cnt;
_tid[cnt]=s;
top[s]=t;
if(son[s]!=0)
dfs2(son[s],t);
int len=map[s].size();
for(int i=0;i<len;i++)
{
int e=map[s][i];
if(e!=fa[s] && e!=son[s])
dfs2(e,e);
}
}
void build(int l,int r,int now)
{
tree[now].l=l;
tree[now].r=r;
tree[now].val=0;
if(l==r)
{
tree[now].val=val[_tid[l]];
return ;
}
int mid=(l+r)>>1;
build(l,mid,now<<1);
build(mid+1,r,now<<1|1);
}
void down(int now)
{
tree[now<<1].val+=tree[now].val;
tree[now<<1|1].val+=tree[now].val;
tree[now].val=0;
}
void update(int l,int r,int now,int num)
{
if(l==tree[now].l && r==tree[now].r)
{
tree[now].val+=num;
return ;
}
if(tree[now].val)
down(now);
int mid=(tree[now].l+tree[now].r)>>1;
if(r<=mid)
update(l,r,now<<1,num);
else if(l>mid)
update(l,r,now<<1|1,num);
else
{
update(l,mid,now<<1,num);
update(mid+1,r,now<<1|1,num);
}
}
void change(int s,int e,int num)
{
while(top[s]!=top[e])
{
if(dep[top[s]]<dep[top[e]])
swap(s,e);
update(tid[top[s]],tid[s],1,num);
s=fa[top[s]];
}
if(dep[s]>dep[e])
swap(s,e);
update(tid[s],tid[e],1,num);
}
int query(int l,int now)
{
if(tree[now].l==l && tree[now].r==l)
return tree[now].val;
if(tree[now].val)
down(now);
int mid=(tree[now].l+tree[now].r)>>1;
if(l<=mid)
return query(l,now<<1);
else
return query(l,now<<1|1);
}
int main()
{
while(cin>>n>>m>>q)
{
memset(size,0,sizeof(size));
memset(fa,0,sizeof(fa));
memset(tid,0,sizeof(tid));
memset(son,0,sizeof(son));
cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
map[i].clear();
}
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
map[a].push_back(b);
map[b].push_back(a);
}
dfs1(1,-1,1);
dfs2(1,1);
build(1,n,1);
while(q--)
{
char ch[5];
int a,b,c;
scanf("%s",ch);
if(ch[0]=='Q')
{
scanf("%d",&a);
printf("%d\n",query(tid[a],1));
}
else
{
scanf("%d%d%d",&a,&b,&c);
if(ch[0]=='I')
change(a,b,c);
else
change(a,b,-c);
}
}
}
}

hdu3966_树链剖分的更多相关文章

  1. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  2. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  3. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  4. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  5. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

  6. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  7. bzoj2243树链剖分+染色段数

    终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...

  8. bzoj3631树链剖分

    虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...

  9. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

随机推荐

  1. [POJ 2282] The Counting Problem

    [题目链接] http://poj.org/problem?id=2282 [算法] 数位DP [代码] #include <algorithm> #include <bitset& ...

  2. TYVJ 1427 线段树的基本操作

    题意: 单点修改,区间最值 思路: 线段树 原题请戳这里 //By SiriusRen #include <cstdio> #include <cstring> #includ ...

  3. fastJson解析复杂对象时碰到的问题

    碰到map对象无法解析出来,发现问题是缺少有get/set方法,否则无法解析. 对象转json字符串 JSON.toJSONString(module) json字符串转对象(必须是pojo) mod ...

  4. BS程序性能调优

    首先想到的是优化算法.改进技术.扩展设备去做优化.其实在讨论性能的时候,绕不开对业务的理解,不同的业务系统对性能的要求不同,优化方式也不一样.优化性能的前提是保证业务的正确性.我们平时关注的性能主要是 ...

  5. 洛谷P2391 白雪皑皑(并查集)

    题目背景 “柴门闻犬吠,风雪夜归人”,冬天,不期而至.千里冰封,万里雪飘.空中刮起了鸭毛大雪.雪花纷纷,降落人间. 美能量星球(pty 在 spore 上的一个殖民地)上的人们被这美景所震撼.但是 p ...

  6. python 模块导入详解

    本文不讨论 Python 的导入机制(底层实现细节),仅讨论模块与包,以及导入语句相关的概念.通常,导入模块都是使用如下语句: import ... import ... as ... from .. ...

  7. 第二次作业&熟悉使用工具

     GIT地址  我的地址  GIT用户名  995020892w  学号后五位  81105  博客地址  我的博客  作业链接  第二次作业 一.环境配置过程 安装vs2017 因为以前学习C#相关 ...

  8. 项目随笔@Service("testService")-------第二篇

    在springmvc中使用注解已经司空见惯了,今天见到了@Service("xxx")这种形式,让我大吃一惊.原来在service后面可以加参数,作为该service的名字,在sp ...

  9. 使用meta实现页面的定时刷新或跳转

    <meta http-equiv="refresh" content="5"> 这个表示当前页面每5秒钟刷一下,刷一下~ <meta http ...

  10. Robot Framework(二)测试数据语法

    2.1.1文件和目录 测试数据的层次结构安排如下: 测试数据在测试数据文件中创建. 测试数据文件会自动创建一个包含该文件中的测试数据的测试套件. 包含测试数据文件的目录构成了更高级别的测试套件.这样的 ...