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

回想一下改动操作:

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

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

没实用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. hdoj--1864--最大保险额(背包)

    最大报销额 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  2. shell 杂集

    1.shell 相等比较注意 -eq 数字相等的比较 == 字符串相等的比较 2.== 和 = 的区别 == 可用于判断变量是否相等,= 除了可用于判断变量是否相等外,还可以表示赋值. = 与 ==  ...

  3. Hadoop MapReduce编程 API入门系列之join(二十六)(未完)

    不多说,直接上代码. 天气记录数据库 Station ID Timestamp Temperature 气象站数据库 Station ID Station Name 气象站和天气记录合并之后的示意图如 ...

  4. mysql5.7 设置密码

    5.7版本的MYSQL的用户表的密码字段与以往版本有所区别, 不再是password字段 而是authentication_string字段. 请注意修改密码: vim  /opt/mysql_d/m ...

  5. Tomcatsession共享方案--memcached-session-manager

    https://github.com/magro/memcached-session-manager/wiki/SerializationStrategies     MSM的特性:    a.支持t ...

  6. meta标签的作用及整理

    [转载] meta的标签的使用是我在前端学习中曾经困惑过一段时间的问题.一方面不是很了解meta标签的用途,另一方面是对于meta标签里的属性和值不是懂,也不知道从哪里冒出来的,所以这篇文章专门整理下 ...

  7. 12.javaweb SQL标签库

    一.说明及使用 1,  首先要知道,开发中绝对不会SQL标签库在JSP中进行数据库操作,学习SQL标签库只是作为一个只是扩展 2,  SQL标签库分类 2.1<sql:setDataSource ...

  8. 【Oracle】回收站

    ☆回收站概念 oracle从10g开始,引入回收站(Recycle Bin)概念.回收站的全称叫:Tablespace Recycle Bin.回收站是一个逻辑区域,oracle并没有为它分配物理空间 ...

  9. matplotlib简介-高质量图形输出

    Matplotlib 是一个用来绘制二维图形的 Python 模块,它克隆了许多 Matlab 中的函数, 用以帮助 Python 用户轻松获得高质量(达到出版水平)的二维图形. 文章来源:http: ...

  10. 【技术累积】【点】【java】【2】聊一聊似曾相识的switch语句

    闲聊 有些东西并不能像爱因斯坦老先生说的那样,书上查的到就不用去记住... 开始 java使用了C的所有流程控制语句: java中同样有switch语句: 大多数情况下,switch都可以用if替换: ...