hdu 3974 Assign the task(线段树+将树映射到区间)
来源:互联网 发布:比特币挖矿用什么软件 编辑:程序博客网 时间:2024/05/19 07:28
Assign the task
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3974
解题思路:
题目大意:
一家公司有n个人,编号1~n,每个人都有一个直属上司。
给你两种操作:
1:给x分配任务y,此时,x会将y也分配给他的下属,下属再分配给下属……也就是x下面的人都会放下原先的任务(如果有)而去
做任务y。
2:询问x当前的任务,若没有则输出-1。
算法思想:
将树映射到区间的线段树。。。
主要是将原有的关系树根据BOSS关系从新编号,
以便把每个BOSS所带领的员工全部压入一个连续区间内,
然后记录每个BOSS的起始编号和他的最后一名的员工的编号,
然后用线段树成端更新,单点查找即可。
AC代码:
#include <bits/stdc++.h>using namespace std;const int maxn = 50005;int fa[maxn],cnt;int sta[maxn],tail[maxn],num[maxn],curTask[maxn];vector<int> g[maxn];struct node{ int l,r,setv;}tree[maxn<<2];void dfs(int u,int fa){ num[u] = ++cnt; curTask[u] = num[u]; sta[u] = cnt;//BOSS的起始编号 int len = g[u].size(); for(int i = 0; i < len; ++i){ if(g[u][i] == fa) continue; dfs(g[u][i],u); } tail[u] = cnt;//该BOSS的最后一名员工的编号}void pushdown(int id){ if(tree[id].setv != -1){ tree[id<<1].setv = tree[id<<1|1].setv = tree[id].setv; tree[id].setv = -1; }}void build(int id,int l,int r){ tree[id].l = l; tree[id].r = r; tree[id].setv = -1; if(l == r){ return; } int mid = (l+r)>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r);}void update(int id,int l,int r,int val){ if(tree[id].l >= l && tree[id].r <= r){ tree[id].setv = val; return; } int mid = (tree[id].l+tree[id].r)>>1; pushdown(id); if(l <= mid) update(id<<1,l,r,val); if(r > mid) update(id<<1|1,l,r,val);}int query(int id,int pos){ if(tree[id].l == tree[id].r) return tree[id].setv; int mid = (tree[id].l+tree[id].r)>>1; pushdown(id); if(pos <= mid) return query(id<<1,pos); else return query(id<<1|1,pos);}int main(){ int T,t = 1; scanf("%d",&T); while(T--){ printf("Case #%d:\n",t++); int n,q; scanf("%d",&n); for(int i = 0; i <= n; ++i) g[i].clear(); memset(fa,0,sizeof(fa)); for(int i=1; i<n; ++i){ int u,v; scanf("%d%d",&u,&v); fa[u] = v; g[u].push_back(v); g[v].push_back(u); } cnt = 0; for(int i=1; i<=n; ++i){ if(fa[i] == 0){ dfs(i,0); break; } } build(1,1,n); scanf("%d",&q); while(q--){ char op[5]; scanf("%s",op); int x,y; scanf("%d",&x); if(op[0]=='C'){ printf("%d\n",query(1,curTask[x])); } else{ scanf("%d",&y); update(1,sta[x],tail[x],y); } } } return 0;}
0 0
- hdu 3974 Assign the task(线段树+将树映射到区间)
- HDU 3974 Assign the task 线段树(树映射到区间)
- HDU - 3974 Assign the task(线段树 区间修改)
- HDU 3974 Assign the task(dfs序 + 线段树区间赋值,单点查询)
- HDU 3974 Assign the task (线段树)
- HDU 3974 Assign the task(线段树)
- hdu 3974 Assign the task (线段树)
- HDU 3974 线段树(将树映射到区间)
- hdu 3974 Assign the task 线段树(时间戳)
- HDU 3974 Assign the task (线段树+dfs序)
- HDU 3974 Assign the task(DFS建树+线段树)
- hdoj 3974 Assign the task 【DFS + 线段树区间修改】
- HDU 3974 Assign the task 图论/线段树区间更新,单点查询
- HDU-3974 Assign the task (dfs序+线段树区间修改点查询)
- HDU 3974 Assign the task——线段树
- HDU 3974 Assign the task (DFS + 线段树)
- HDU3974-Assign the task(线段树+区间建树)
- Assign the task (线段树)
- PAT (Advanced Level) Practise 1076 Forwards on Weibo (30)
- Maven依赖范围
- 经典的Java基础面试题
- 星号图
- PHP异常处理方法
- hdu 3974 Assign the task(线段树+将树映射到区间)
- 顺序栈
- Action Bar(title文字大小问题 基本运用)
- OC2-1
- Ajax初步学习
- android 了解你的APP如何使用内存
- 微信公众平台之模拟登录
- hdoj 1068 Girls and Boys 【匈牙利算法&&二分图匹配】
- poj2533 Longest Ordered Subsequence(最长上升子序列)