题意:一共有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建树+区间覆盖+单点查询)的更多相关文章

  1. 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 ...

  2. HDU 3974 Assign the task(dfs建树+线段树)

    题目大意:公司里有一些员工及对应的上级,给出一些员工的关系,分配给某员工任务后,其和其所有下属都会进行这项任务.输入T表示分配新的任务, 输入C表示查询某员工的任务.本题的难度在于建树,一开始百思不得 ...

  3. HDU 3974 Assign the task (DFS序 + 线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操 ...

  4. HDU 3974 Assign the task (DFS+线段树)

    题意:给定一棵树的公司职员管理图,有两种操作, 第一种是 T x y,把 x 及员工都变成 y, 第二种是 C x 询问 x 当前的数. 析:先把该树用dfs遍历,形成一个序列,然后再用线段树进行维护 ...

  5. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  6. HDU 3974 Assign the task

    Assign the task Problem Description There is a company that has N employees(numbered from 1 to N),ev ...

  7. hdu 3974 Assign the task(dfs序上线段树)

    Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...

  8. HDU 3974 Assign the task 并查集/图论/线段树

    Assign the task Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  9. HDU 3974 Assign the task(简单线段树)

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. tensorflow学习笔记——常见概念的整理

    TensorFlow的名字中已经说明了它最重要的两个概念——Tensor和Flow.Tensor就是张量,张量这个概念在数学或者物理学中可以有不同的解释,但是这里我们不强调它本身的含义.在Tensor ...

  2. 在.NET CORE中使用配置文件:对 ConfigurationBuilder 的使用说明

    示例:ASP.NET MVC 使用示例: 如何覆写默认行为?如取消热更新支持,方法如下: 示例:控制台 使用应用程序参数 使用键值对枚举(这里以字典来说明) 使用JSON文件 注册配置文件中的某一个段 ...

  3. 异步编程CompletableFuture实现高并发系统优化之请求合并

    先说场景: 根据Redis官网介绍,单机版Redis的读写性能是12万/秒,批量处理可以达到70万/秒.不管是缓存或者是数据库,都有批量处理的功能.当我们的系统达到瓶颈的时候,我们考虑充分的压榨缓存和 ...

  4. unimrcp-voice-activity语音检测

    研究 unimrcp有一段时间了,其中unimrcp voice acitve的算法,是遭到大家频繁吐槽.今天我们简单的介绍一下unimrcp voice activity 的这个简单粗暴的算法: u ...

  5. 基于RobotFramework实现自动化测试

    Java + robotframework + seleniumlibrary 使用Robot Framework Maven Plugin(http://robotframework.org/Mav ...

  6. 01-WIN2012R2+SQL2016故障转移群集的搭建

    一.前期准备  1.1.准备4台机器 机器名 IP 功能 jf-yukong 192.168.10.200 做域控服务器 Jf-storage 192.168.10.201 做ISCSI存储服务器 J ...

  7. Hive安装与部署

    进去root权限(su) 1.从https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-1.2.2/apache-hive-1.2.2-bin.ta ...

  8. 析构函数中调用 Dispose 报错 :Internal .Net Framework Data Provider error 1.[非原创]

    搜索MSDN的资源可以找到答案: 原文如下http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=473449&SiteID=1 以下是关于 ...

  9. 剑指offer总结一:字符、数字重复问题

    问题1:字符串中第一个不重复的字符 题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是" ...

  10. bootstrap-datetimepicker时间插件使用

    html头部引入相关的js和css <link rel="stylesheet" type="text/css" href="css/boots ...