HDU - 3974 Assign the task (DFS建树+区间覆盖+单点查询)
题意:一共有n名员工, n-1条关系, 每次给一个人分配任务的时候,(如果他有)给他的所有下属也分配这个任务, 下属的下属也算自己的下属, 每次查询的时候都输出这个人最新的任务(如果他有), 没有就输出-1。
题解:需要用DFS建树来确立关系, 然后用线段树进行区间覆盖。
DFS建树: 从Boss 开始dfs,通过dfs递归时编号出现的先后顺序来确定某个员工对应的起点与终点。
样例的关系图是这样的
当dfs建树跑完了之后各个节点对应的位置是这样的
其中Start表示这个节点本身的新编号和这个节点管辖区间内的左端点 End表示这个点管辖区间内的右端点
从右边的图中可以看见其中的最上级2号员工(Boss), 他的管辖区间是[1,5],能覆盖所有人的结点, 5号员工他没有下属所以他的End值就等于Start值。
(发布于第二天的修改, 竟然被吐槽写的不好理解, 非要我再加上下面这幅图)
上面这幅图呢就是线段树下的员工状态图了, 假设我们现在对2号员工分配任务y1
那我们就需要对2号员工的管辖区域[1,5]区间的值都修改成y1。
再注意一下 管辖区域的左端点 还代表的这名员工在线段树下的区间下标是多少。
2号员工的管辖区域是[1,5] 所以他就在位置1。
管辖区域的右端点就是自己最多能管到员工的编号。
所以每次对自己的管辖区域进行线段树区域更新操作就可以将每个人的任务分配下去了。
这样每次查询某个员工的任务的时候只需要将lazy标记推到底,就能找到最后收到的任务了。
用DFS去访问每个节点,并将访问的顺序编号,当DFS遍历了整个关系图之后,每个人的管辖区间就确定下来了,然后就可以通过管辖区间来进行线段树区域覆盖和单点查询操作。
int cnt = ;
void dfs(int n)
{
Start[n] = ++cnt;
int m = son[n].size();
for(int i = ; i < m; i++)
dfs(son[n][i]);//已经用vector son[n] 来存好了每个人的下属
End[n] = cnt;
}
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int N = +;
vector<int> son[N];
int Start[N], End[N];
int tree[N<<], lazy[N<<];
bool vis[N];
int cnt = ;
void dfs(int n)
{
Start[n] = ++cnt;
int m = son[n].size();
for(int i = ; i < m; i++)
dfs(son[n][i]);
End[n] = cnt;
}
void PushDown(int rt)
{
if(lazy[rt] != -)
{
tree[rt<<] = tree[rt<<|] = lazy[rt<<|] = lazy[rt<<] = lazy[rt];
lazy[rt] = -;
}
}
void Revise(int L, int R, int C, int l, int r, int rt)
{
if(L <= l && r <= R)
{
lazy[rt] = tree[rt] = C;
return ;
}
PushDown(rt);
int m =l+r >> ;
if(L <= m) Revise(L,R,C,lson);
if(m < R) Revise(L,R,C,rson);
}
int Query(int L, int l, int r, int rt)
{
if(l == r)
{
return tree[rt];
}
int m = l+r >> ;
PushDown(rt);
if(L <= m) return Query(L,lson);
else return Query(L,rson);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
int T;
cin >> T;
for(int i = ; i <= T; i++)
{
cout << "Case #" << i << ":\n";
int n, u, v;
cnt = ;
cin >> n;
for(int i = ; i <= n; i++)
son[i].clear(), vis[i] = ;
for(int i = ; i < n; i++)
{
cin >> u >> v;
son[v].push_back(u);//用vector去对应的关系
vis[u] = ;//如果某个点成为过下属就标记一下 没有标记过的那个人就是Boss(最上级)
}
int pos = -;
for(int i = ; i <= n; i++)
if(vis[i])
{
pos = i;
break;
}
dfs(pos);//从最上级的人开始递归, 找到每个人对应的区间
memset(tree, -, sizeof(tree));//因为没有接到任务过的人查询的时候输出-1
memset(lazy, -, sizeof(lazy));//所以直接memset为-1就好了,不需要再进行特判
int t;
cin >> t;
string str;
int x, y;
while(t--)
{
cin >> str;
if(str[] == 'C')
{
cin >> x;
cout << Query(Start[x],,cnt,) << endl;
}
else
{
cin >> x >> y;
Revise(Start[x],End[x],y,,cnt,);
}
}
}
return ;
}
HDU - 3974 Assign the task (DFS建树+区间覆盖+单点查询)的更多相关文章
- HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)
描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...
- HDU 3974 Assign the task(dfs建树+线段树)
题目大意:公司里有一些员工及对应的上级,给出一些员工的关系,分配给某员工任务后,其和其所有下属都会进行这项任务.输入T表示分配新的任务, 输入C表示查询某员工的任务.本题的难度在于建树,一开始百思不得 ...
- HDU 3974 Assign the task (DFS序 + 线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操 ...
- HDU 3974 Assign the task (DFS+线段树)
题意:给定一棵树的公司职员管理图,有两种操作, 第一种是 T x y,把 x 及员工都变成 y, 第二种是 C x 询问 x 当前的数. 析:先把该树用dfs遍历,形成一个序列,然后再用线段树进行维护 ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- HDU 3974 Assign the task
Assign the task Problem Description There is a company that has N employees(numbered from 1 to N),ev ...
- hdu 3974 Assign the task(dfs序上线段树)
Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...
- HDU 3974 Assign the task 并查集/图论/线段树
Assign the task Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- HDU 3974 Assign the task(简单线段树)
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- 【MySQL】日常小技巧汇总,更新中……
创建表时修改自增主键,添加 AUTO_INCREMENT=<Number> ,例如: CREATE TABLE `table_name` ( `id` int(11) unsigned N ...
- 【Python-Django后端】用户注册通用逻辑,用户名、手机号重名检测,注册成功后状态保持!!!
用户注册后端逻辑 1. 接收参数 username = request.POST.get('username') password = request.POST.get('password') pas ...
- vue在窗口大小改变时强制刷新组件的方法
mounted () { window.onresize = () => { return (() => { this.$forceUpdate(); })() } }
- [NUnit] discover test finished: 0 found issue
%Temp%\VisualStudioTestExplorerExtensions & restart visual studio
- Opengl_入门学习分享和记录_01_Graphics Pipeline(图形渲染管线)
写在前面的废话: 这个系列拖更了很久,很大一定程度上是由于自己最近忙着高数学习和线代学习..感觉时间特别紧缺(其实就是我太懒了)好了不废话了,总结开始. 正文开始: 首先Graphics Pipeli ...
- linux应用问题分析命令
1. 描述 应用问题分析方式及命令有很多,一般都结合着使用,今天主要介绍下: (1)top命令,实时查看服务器资源使用情况,类似windows下的资源管理器: (2)tail命令,实时刷新查看日志命令 ...
- LeetCode_62_不同路径
/** * @author jianw.li * @date 2019/1/22 11:11 PM * @Description: 不同路径 * 一个机器人位于一个 m x n 网格的左上角 (起始点 ...
- 面试java后端面经_4
作者:早该变坏链接:https://www.nowcoder.com/discuss/157627来源:牛客网 情话部分: 当有自己心仪的小姐姐,又没确定关系,有时候分享彼此爱情观的时候,你就可以开始 ...
- CSV Data Set Config 拓展开发
1.目的 在日常的性能测试项目中,经常会遇到参数化的问题,我们所熟知的LR工具对参数化支持非常友好,然而JMeter相对逊色一些.大家都知道在使用JMeter工具参数化时常用CSV Data Set ...
- map redcue filter sorted函数
sorted 函数 接收一个key函数来实现自定义的排序 # 训练集和验证集的文件命名不一样 # test1: data/test1/8973.jpg # train: data/train/cat. ...