HDOJ-3974(线段树,区间修改点查询)

来源:互联网 发布:淘宝信用贷款怎么审查 编辑:程序博客网 时间:2024/06/01 10:22

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3974

分析:修改父节点的值,所有子节点的值都被修改,典型的线段树操作,即修改代表整个区间的父节点,则区间内的所有点都被修改,一个问题是,这颗树并不是天然的线段树,因此需要先将原来的节点映射到对应的区间,这一点借助先序遍历dfs形成的自然顺序即可完成,并且父节点一方面代表整个区间,另一方面映射成区间左端点,而区间右端点则是最后一个孩子节点,接下来就是一般的线段树区间修改点查询操作了。

虽然思路有,但还是WA了2次,分别是因为初始化没有注意边界条件导致SE,查询没有进行pushdown,还是要细心啊。。。


#include <cstdio>#include <cstring>#define MAX50005int N, M, from[MAX], to[MAX], dfsClock;int l[MAX << 2], r[MAX << 2], v[MAX << 2];struct Edge{int to, next;} edge[MAX];int nex, pre[MAX];bool hasParent[MAX];inline void addEdge(int x, int y){edge[nex].to = y;edge[nex].next = pre[x];pre[x] = nex++;}void dfs(int x){from[x] = ++dfsClock;for(int i = pre[x]; i; i = edge[i].next) dfs(edge[i].to);to[x] = dfsClock;}void build(int i, int L, int R){l[i] = L; r[i] = R; v[i] = -1;if(L == R) return;int M = (L + R) >> 1;build(i << 1, L, M);build(i << 1 | 1, M+1, R);}inline void pushDown(int i){if(v[i] != -1) v[i << 1] = v[i << 1 | 1] = v[i];}inline void popUp(int i){v[i] = v[i << 1] != v[i << 1 | 1] ? -1 : v[i << 1];}int query(int i, int x){if(v[i] != -1 || l[i] == r[i]) return v[i];pushDown(i);int m = (l[i] + r[i]) >> 1;if(m < x) return query(i << 1 | 1, x);return query(i << 1, x);}void update(int i, int L, int R, int V){if(L <= l[i] && r[i] <= R){v[i] = V;return;}pushDown(i);int m = (l[i] + r[i]) >> 1;if(m >= R) update(i << 1, L, R, V);else if(m < L) update(i << 1 | 1, L, R, V);else{update(i << 1, L, m, V);update(i << 1 | 1, m+1, R, V);}popUp(i);}void build(){nex = 1; dfsClock = 0;memset(pre + 1, 0, N * sizeof(int));memset(hasParent + 1, false, N);//input node countscanf("%d", &N);//build segment treebuild(1, 1, N);//build graphint i, x, y;for(i = 1; i < N; ++i){scanf("%d%d", &y, &x);addEdge(x, y);hasParent[y] = true;}//find out each node's representing intervalfor(i = 1; i <= N; ++i){if(!hasParent[i]) break;}dfs(i);}void work(){scanf("%d", &M);char s[4];int x, y;while(M--){scanf("%s%d", s, &x);if(s[0] == 'C') printf("%d\n", query(1, from[x]));else{scanf("%d", &y);update(1, from[x], to[x], y);}}}int main(){int t = 1, test;for(scanf("%d", &test); t <= test; ++t){printf("Case #%d:\n", t);build();work();}return 0;}

0 0
原创粉丝点击