首页 > 代码库 > hdu 3974 Assign the task(线段树)
hdu 3974 Assign the task(线段树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3974
题意:给定一棵树,50000个节点,50000个操作,C x表示查询x节点的值,T x y表示更新x节点及其子节点的值为y
大致把边存一下那一棵树来举例子
2
3 5
4 1
例如像这样的一棵树,可以将2->1,3->2,4->3,1->4,5->5按照dfs序来编号,然后用线段树进行区间修改,稍微想一想
应该都会了。
#include <iostream>#include <cstring>#include <vector>using namespace std;const int M = 5e4 + 10;vector<int>vc[M];int pre[M] , dig[M] , length[M] , cnt;void dfs(int pos) { if(vc[pos].size() == 0) { return ; } int len = vc[pos].size(); for(int i = 0 ; i < len ; i++) { dig[vc[pos][i]] = ++cnt; dfs(vc[pos][i]); length[vc[pos][i]] = cnt; }}struct TnT { int l , r , num , add;}T[M << 2];void build(int l , int r , int p) { int mid = (l + r) >> 1; T[p].l = l , T[p].r = r , T[p].add = -1 , T[p].num = -1; if(T[p].l == T[p].r) { return ; } build(l , mid , p << 1); build(mid + 1 , r , (p << 1) | 1);}void pushdown(int p) { if(T[p].add != -1) { T[p << 1].num = T[p].add; T[(p << 1) | 1].num = T[p].add; T[p << 1].add = T[p].add; T[(p << 1) | 1].add = T[p].add; T[p].add = -1; }}void updata(int l , int r , int p , int ad) { int mid = (T[p].l + T[p].r) >> 1; if(T[p].l == l && T[p].r == r) { T[p].num = ad; T[p].add = ad; return ; } pushdown(p); if(mid >= r) { updata(l , r , p << 1 , ad); } else if(mid < l) { updata(l , r , (p << 1) | 1 , ad); } else { updata(l , mid , p << 1 , ad); updata(mid + 1 , r , (p << 1) | 1 , ad); }}int query(int pos , int p) { int mid = (T[p].l + T[p].r) >> 1; if(T[p].l == T[p].r && T[p].l == pos) { return T[p].num; } pushdown(p); if(mid >= pos) { return query(pos , p << 1); } else { return query(pos , (p << 1) | 1); }}int main() { int t; int ans = 0; scanf("%d" , &t); while(t--) { int n; ans++; scanf("%d" , &n); for(int i = 0 ; i <= n ; i++) { vc[i].clear(); pre[i] = -1; } for(int i = 0 ; i < n - 1 ; i++) { int x , y; scanf("%d%d" , &x , &y); vc[y].push_back(x); pre[x] = y; } int temp = -1; for(int i = 1 ; i <= n ; i++) { if(pre[i] == -1) { temp = i; break; } } cnt = 0; dig[temp] = ++cnt; length[temp] = n; dfs(temp); int m; scanf("%d" , &m); char cp[2]; printf("Case #%d:\n" , ans); build(1 , n , 1); while(m--) { int x , y; scanf("%s" , cp); if(cp[0] == ‘C‘) { scanf("%d" , &x); printf("%d\n" , query(dig[x] , 1)); } if(cp[0] == ‘T‘) { scanf("%d%d" , &x , &y); updata(dig[x] , length[x] , 1 , y); } } } return 0;}
hdu 3974 Assign the task(线段树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。