题意:一共有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. Python实现批量处理扫描特定目录

    ## 简述在渗透测试中遇到相同CMS站点时,搞定一个站点,相当于拿了一个站群的通用漏洞,所以我们首先需要标注站点的CMS类型,根据要求编写如下脚本 ## 要求1.访问特定目录,如:站点特定 /cmsa ...

  2. Hibernate 框架

    首先,我们先来了解一下什么是 Hibernate 框架. 什么是 Hibernate 框架? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO ...

  3. Unity的赛车游戏实现思路

    unity目前版本实现赛车的技术方案主要有3种: 1.wheelCollider,设置motorTorque.brakeTorque.steerAngle来实现车子的推动和转弯,优点是上手简单,而且很 ...

  4. SonarQube部署及代码质量扫描入门教程

    一.前言 1.本文主要内容 CentOS7下SonarQube部署 Maven扫描Java项目并将扫描结果提交到SonarQube Server SonarQube扫描报表介绍 2.环境信息 工具/环 ...

  5. pdf.js跨域加载文件

    pdf.js一个基于Html的工具类,熟悉pdf.js的朋友们很清楚,pdf.js帮助我们做了很多事.尤其金融类网站会产生很多的报表.需要在线预览.pdf.js绝对是我们的首选 本地预览 在pdf.j ...

  6. 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫

    前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,本文记录免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作 ...

  7. Linux:oracle11.2.0dbca静默建库

    1.关闭防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止firewall ...

  8. LoRaWAN_stack移植笔记(七)_数据包的接收发送

    以下的代码适用于LoRa sx1276点对点的通讯,纯粹的考虑在非发射模式下即为接收模式 配置sx1276的射频参数,并且切换到接收模式 //bandwidth [0:125 1:250 2:500] ...

  9. 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[1]:验证模型

    CKB 脚本编程简介[1]: 验证模型 本文作者:Xuejie 原文链接:Introduction to CKB Script Programming 1: Validation Model 本文译者 ...

  10. 关于Picasso加载图片Callback不执行问题

    关于Picasso加载图片Callback不执行问题 问题背景 代码大致如下,Target或Callback的回调有时候不执行. https://github.com/square/picasso/i ...