Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)
题目链接:
题目描述:
给出一个树,每个节点都有一个权值,有三种操作:
1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x;
2:( D, i, j, x ) 从i到j的路径上经过的节点全部都减去x;
3:(Q, x) 查询节点x的权值为多少?
解题思路:
可以用树链剖分对节点进行hash,然后用线段树维护(修改,查询),数据范围比较大,要对线段树进行区间更新
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = ;
#define lson(x) 2*x+1
#define rson(x) 2*x+2 struct e
{
int to, next;
}edge[maxn*];
struct node
{
int l, r, val, x;
int Mid ()
{
return (l+r)/;
}
}tree[maxn*];
int val[maxn], x[maxn], deep[maxn], size[maxn], tot, num;
int son[maxn], top[maxn], id[maxn], head[maxn], fa[maxn]; void init ()
{
num = tot =;
memset (head, -, sizeof(head));
} void Add (int from, int to)
{
edge[tot].to = to;
edge[tot].next = head[from];
head[from] = tot ++;
} //找重边
void dfs1 (int u, int f, int dep)
{
son[u] = ;
fa[u] = f;
deep[u] = dep;
size[u] = ; for (int i=head[u]; i!=-; i=edge[i].next)
{
int v = edge[i].to;
if (v == f) continue;
dfs1 (v, u, dep+);
size[u] += size[v];
if (size[son[u]] < size[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!=-; i=edge[i].next)
{
int v = edge[i].to;
if (v == fa[u] || v == son[u]) continue;
dfs2 (v, v);
}
} //区间更新线段树,向下一层更新
void pushup (int x)
{
tree[lson(x)].x += tree[x].x;
tree[rson(x)].x += tree[x].x;
tree[lson(x)].val += tree[x].x;
tree[rson(x)].val += tree[x].x;
tree[x].x = ;
} void build (int root, int l, int r)
{
tree[root].l = l;
tree[root].r = r;
tree[root].x = tree[root].val = ; if (l == r)
{
tree[root].val = val[l];
return ;
} build (lson(root), l, tree[root].Mid());
build (rson(root), tree[root].Mid()+, r);
} void updata (int root, int l, int r, int x)
{
if (tree[root].l == l && r == tree[root].r)
{
tree[root].val += x;
tree[root].x += x;
return ;
} if (tree[root].x)
pushup (root); if (r <= tree[root].Mid())
updata (lson(root), l, r, x);
else if (tree[root].Mid() < l)
updata (rson(root), l, r, x);
else
{
updata (lson(root), l, tree[root].Mid(), x);
updata (rson(root), tree[root].Mid()+, r, x);
}
} int query (int root, int x)
{
if (tree[root].l == tree[root].r && tree[root].l == x)
return tree[root].val; if (tree[root].x)
pushup (root); if (x <= tree[root].Mid())
query (lson(root), x);
else
query (rson(root), x);
} //处理节点u,v
void alter (int u, int v,int x)
{
int tp1 = top [u];
int tp2 = top [v]; while (tp1 != tp2)
{//两个节点不在同一个重链上
if (deep[tp1] < deep[tp2])
{
swap (tp1, tp2);
swap (u, v);
}//deep深的重链上升 updata (, id[tp1], id[u], x);
u = fa[tp1];
tp1 = top[u];
} //在同一条重链上
if (deep[u] > deep[v])
swap (u, v);
updata (, id[u], id[v], x); } int main ()
{
int n, m, q; while (scanf ("%d %d %d", &n, &m, &q) != EOF)
{
init ();
for (int i=; i<=n; i++)
scanf ("%d", &x[i]);
for (int i=; i<m; i++)
{
int x, y;
scanf ("%d %d", &x, &y);
Add (x, y);
Add (y, x);
} dfs1 (, , );
dfs2 (, ); //hash原来节点
for (int i=; i<=n; i++)
val[id[i]] = x[i];
build (, , n); while (q --)
{
char str[];
int l, r, x;
scanf ("%s", str); if (str[] == 'Q')
{
scanf ("%d", &x);
printf ("%d\n", query (, id[x]));
}
else if (str[] == 'I')
{
scanf ("%d %d %d", &l, &r, &x);
alter (l, r, x);
}
else
{
scanf ("%d %d %d", &l, &r, &x);
alter (l, r, -x);
} }
}
return ;
}
Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)的更多相关文章
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
随机推荐
- 浅谈JavaScript的事件(事件流)
事件流描述的是从页面中接收事件的顺序.IE的事件流失事件冒泡,而Netspace的事件流失事件捕获. 事件冒泡 IE的事件流叫事件冒泡,即事件开始时,由具体的元素(文档中嵌套层次最深的节点)接收,然 ...
- My app status is Ready for Sale but I cannot see my app on the App Store. Why? 为什么审核通过后 appstore中搜不到我的app
这是苹果的官方解答 The following factors could prevent your app from showing up on the App Store: Make sure t ...
- 火焰灯menu修改之后,可以实现数遍点击小方块停留在当前页面
下载地址:http://www.cnblogs.com/RightDear/admin/Files.aspx 调用方式,传入一个参数 首页传入0,关于联盟传入1,产品展示传入2,依此类推 <sc ...
- SpringInAction4笔记——装配
重点:常用的上下文环境 AnnotationConfigApplicationContext ClassPathXmlApplicationContext FileSystemXmlApplicati ...
- spring中PropertyPlaceholderHelper替换占位符的值
1.Properties中的值替换¥{}或者#{}占位符 String text = "foo=${foo},bar=${bar}"; Properties props = new ...
- mysql优化----大数据下的分页,延迟关联,索引与排序的关系,重复索引与冗余索引,索引碎片与维护
理想的索引,高效的索引建立考虑: :查询频繁度(哪几个字段经常查询就加上索引) :区分度要高 :索引长度要小 : 索引尽量能覆盖常用查询字段(如果把所有的列都加上索引,那么索引就会变得很大) : 索引 ...
- JavaScript数组遍历:for、foreach、for in、for of、$.each、$().each的区别
一.for Javascript中的for循环,它用来遍历数组 var arr = [1,2,3,4] for(var i = 0 ; i< arr.length ; i++){ console ...
- UVA11624 Fire! —— BFS
题目链接:https://vjudge.net/problem/UVA-11624 题解: 坑点:“portions of the maze havecaught on fire”, 表明了起火点不唯 ...
- 启动vmware中的虚拟机的时候,提示Failed to lock the file
http://www.vixual.net/blog/archives/842 VMware Server 當掉後重新啟動 Guest OS 時,出現 cannot open the disk '*. ...
- html5--6-2 CSS语法
html5--6-2 CSS语法 实例 学习要点 掌握引入外部样式表方法 插入样式的三种方法 内联样式表(行内) 内部样式表(style中) 外部样式表 创建一个外部样式表 在head中使用link元 ...