HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)
题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树)。当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工作),题目会询问你其中某个人正在做的工作。
解题思路:其实从“一个人分配他的下属做一样的工作”这里就可以看出来了,这相当于让一块区间的人都做一样的事,就是线段树区间染色问题。但不能使用线段树,要先将多叉树铺展开,将节点映射到线段上。把每个人的管理区段找出来(把属于同一个人管的放一起,上司放在前面),这样对某个员工更新也就是对他和他下属的更新。具体实现就是先将多叉树保存下来,用dfs遍历多叉树给每个人打上时间戳,分配序号就行了。
#include<iostream>
#include<cstring>
#include<vector>
#define LC(a) ((a<<1))
#define RC(a) ((a<<1)+1)
#define MID(a,b) ((a+b)>>1)
using namespace std;
const int N=5e4+;
typedef long long ll; vector<ll>v[N];
ll Start[N],End[N];//每个员工所有下属的开始和结束节点,包含本身
ll ans,cnt;//cnt用于记录节点的编号
bool used[N]; void dfs(ll rt){
Start[rt]=++cnt;
for(int i=;i<v[rt].size();i++){
dfs(v[rt][i]);
}
End[rt]=cnt;
} struct node{
ll l,r;
ll task;//task=-2表示下属工作不同
}tree[N*]; void pushup(ll p){
tree[p].task=(tree[LC(p)].task==tree[RC(p)].task?tree[LC(p)].task:-);
} void pushdown(ll p){
tree[LC(p)].task=tree[RC(p)].task=tree[p].task;
} void build(ll p,ll l,ll r){
tree[p].l=l;
tree[p].r=r;
tree[p].task=-;
if(l==r){
return;
}
build(LC(p),l,MID(l,r));
build(RC(p),MID(l,r)+,r);
} void update(ll p,ll l,ll r,ll task){
if(r<tree[p].l||l>tree[p].r)
return;
if(l<=tree[p].l&&r>=tree[p].r){
tree[p].task=task;
return;
}
if(tree[p].task!=-)
pushdown(p);
update(LC(p),l,r,task);
update(RC(p),l,r,task);
pushup(p);
} void query(ll p,ll t){
if(tree[p].task!=-){
ans=tree[p].task;
return;
}
ll mid=MID(tree[p].l,tree[p].r);
if(t<=mid)
query(LC(p),t);
else
query(RC(p),t);
} int main(){
ios::sync_with_stdio(false);
ll t;
ll cas=;
cin>>t;
while(t--){
cas++;
//初始化
cnt=;
memset(used,false,sizeof(used));
for(int i=;i<=N;i++){
v[i].clear();
} ll n;
cin>>n;
for(int i=;i<=n-;i++){
ll rt,chd;
cin>>chd>>rt;
used[chd]=true;
v[rt].push_back(chd);
}
//将多叉树转化为线段
for(int i=;i<=n;i++){
//找到根结点
if(!used[i]){
dfs(i);
break;
}
}
//建树
build(,,n);
ll m;
cout<<"Case #"<<cas<<":"<<endl;
cin>>m;
for(int i=;i<=m;i++){
char op;
cin>>op;
if(op=='C'){
ll x,t;
cin>>x;
t=Start[x];
query(,t);
cout<<ans<<endl;
}
else{
ll x,l,r,task;
cin>>x>>task;
l=Start[x];
r=End[x];
update(,l,r,task);
}
}
}
}
HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)的更多相关文章
- hdu 5023(线段树区间染色,统计区间内颜色个数)
题目描述:区间染色问题,统计给定区间内有多少种颜色? 线段树模板的核心是对标记的处理 可以记下沿途经过的标记,到达目的节点之后一块算,也可以更新的时候直接更新到每一个节点 Lazy操作减少修改的次数( ...
- 线段树区间染色 ZOJ 1610
Count the Colors ZOJ - 1610 传送门 线段树区间染色求染色的片段数 #include <cstdio> #include <iostream> #in ...
- HDU-3974 Assign the task(多叉树DFS时间戳建线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=3974 Time Limit: 15000/5000 MS (Java/Others) Memory Lim ...
- hdu3974 Assign the task dfs序+线段树
There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...
- HDU 3974 Assign the task 并查集/图论/线段树
Assign the task Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- HDU3974 Assign the task
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- POJ 1436 (线段树 区间染色) Horizontally Visible Segments
这道题做了快两天了.首先就是按照这些竖直线段的横坐标进行从左到右排序. 将线段的端点投影到y轴上,线段树所维护的信息就是y轴区间内被哪条线段所覆盖. 对于一条线段来说,先查询和它能相连的所有线段,并加 ...
- ZOJ1610 Count the Colors —— 线段树 区间染色
题目链接:https://vjudge.net/problem/ZOJ-1610 Painting some colored segments on a line, some previously p ...
- hdu3974 Assign the task【线段树】
There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...
随机推荐
- 【LOJ6436】【PKUSC2018】神仙的游戏(NTT)
[LOJ6436][PKUSC2018]神仙的游戏(NTT) 题面 LOJ 题解 看到\(zsy\)从\(PKUSC\)回来就秒掉了这种神仙题 吓得我也赶快看了看\(PKUSC\)都有些什么神仙题 然 ...
- Unity3D for VR 学习(4): 自绘摄像机的视口区域锥体
在Unity Editor下,当选择Camera组件后,可呈现出Camera视口区域锥体,非常方便.但是当选择其他物体,如Cube后,就无法得知是否在Camera市口区内了,这里我找到了雨松MOMO的 ...
- 升级系统后maxvim不能用,重新下载编译个
1. 获取macvim源代码git clone https://github.com/b4winckler/macvim.git 2 配置及编译 编译选项 ./configure --with-fea ...
- 学习 opencv---(13)opencv霍夫变换:霍夫线变换,霍夫圆变换
在本篇文章中,我们将一起学习opencv中霍夫变换相关的知识点,以及了解opencv中实现霍夫变换的HoughLines,HoughLinesP函数的使用方法,实现霍夫圆变换的HoughCircles ...
- Jenkins+SVN+Maven发布项目
一.安装jenkins插件 登入Jenkis后,安装几个插件: Maven Integration plugin # 没有这个插件,不能创建maven项目 Subversion Plug-in Pub ...
- HTML5增强的表单
form元素a.用来定义一个表单,是建立表单的基础元素(就类似定义表格的table)b.表单的其他元素包含在form元素中,其主要子元素有:input/button/select......form元 ...
- How To Build Compelling Stories From Your Data Sets
How To Build Compelling Stories From Your Data Sets Every number has a story. As a data scientist, y ...
- Java实现线性表-顺序表示和链式表示
顺序表示和链式表示的比较: 1.读写方式:顺序表可以顺序存取,也可以随机存取:链表只能从表头顺序存取元素: 2.逻辑结构与物理结构:顺序存储时,逻辑上相邻的元素其对应的物理存储位置也相邻:链式存储时, ...
- 51nod1056 最长等差数列 V2
基准时间限制:8 秒 空间限制:131072 KB 分值: 1280 N个不同的正整数,从中选出一些数组成等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括 ...
- Tomcat面试题目
1.tomcat给你你怎样去调优? 1. JVM参数调优:-Xms<size> 表示JVM初始化堆的大小,-Xmx<size>表示JVM堆的最大值.这两个值的大小一般根据需要进 ...