hdu3966_树链剖分
近期在强化知识点深度。发现树链剖分不是非常会写了。
回想一下改动操作:
若两个点在同一条链上,则直接改动这段区间。
若不在同一条链上,改动深度较大的点到其链顶端的区间,同一时候将这个点变为他所在链顶端的父亲,循环操作直到这两个点在同一条链上。就能够用上一种方法了。
没实用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_树链剖分的更多相关文章
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- bzoj2243树链剖分+染色段数
终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...
- bzoj3631树链剖分
虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
随机推荐
- [HTML5] 新标签解释及用法
转自:http://www.cnblogs.com/yuzhongwusan/archive/2011/11/17/2252208.html HTML 5 是一个新的网络标准,目标在于取代现有的 HT ...
- resgen.exe 已退出 代码为 1073741701的错误的解决办法
以管理员的身份打开命令提示窗口:(开始-运行-cmd),更改目录至"CD C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\”下 ...
- Object的wait和Thread的sleep
Object的wait() wait()搭配notify(),nofityAll()使用. 线程获取到对象锁之后,执行wait()就会释放对象锁,同时线程挂起,直到其他线程获取到对象锁并执行notif ...
- 【Oracle】权限
1. 授予权限: GRANT privilege[, privilege...] TO user [, user| role, PUBLIC...]; ①DBA授予用户系统权限 GRANT creat ...
- Verilog之$sreadmemb
1 Memories Memories file format is shown below, the address is specified as @ <address> in he ...
- Solid Angle of A Cubemap Texel - 计算Cubemap的一个像素对应的立体角的大小
参考[http://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/] 计算diffuse irradiance map或者求解sh ...
- 「CorelDRAW降价提醒」,您关注的商品已降价!
不管是“光棍节”还是“剁手节” 似乎和我都没有什么关系 事实证明,我错了 今天,早上竟然有不识趣的人发红包祝我单身快乐 纳尼,有没有搞错? 我能直接怼回去,说不领么? 但好像又不是我的风格 哎,一个红 ...
- idea中SVN的运用
1.1.1 上传代码时可以指定忽略一些上传目录 1.1.2 设置项目上传的路径 1.1.3 解决上传路径中包含“svn”目录问题 上传 从 SVN 服务器中检出代码到工作空间
- BZOJ 1835 [ZJOI2010]基站选址 (线段树优化DP)
题目大意:略 洛谷题面传送门 BZOJ题面传送门 注意题目的描述,是村庄在一个范围内去覆盖基站,而不是基站覆盖村庄,别理解错了 定义$f[i][k]$表示只考虑前i个村庄,一共建了$k$个基站,最后一 ...
- keepalived实现IP地址高可用
yum -y install keepalived vim /etc/keepalived/keepalived.conf global_defs { router_id LVS_DEVEL_ngin ...