题目大意:有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(多叉树转换为线段+线段树区间染色)的更多相关文章

  1. hdu 5023(线段树区间染色,统计区间内颜色个数)

    题目描述:区间染色问题,统计给定区间内有多少种颜色? 线段树模板的核心是对标记的处理 可以记下沿途经过的标记,到达目的节点之后一块算,也可以更新的时候直接更新到每一个节点 Lazy操作减少修改的次数( ...

  2. 线段树区间染色 ZOJ 1610

    Count the Colors ZOJ - 1610 传送门 线段树区间染色求染色的片段数 #include <cstdio> #include <iostream> #in ...

  3. HDU-3974 Assign the task(多叉树DFS时间戳建线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=3974 Time Limit: 15000/5000 MS (Java/Others)    Memory Lim ...

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

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

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

  6. HDU3974 Assign the task

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

  7. POJ 1436 (线段树 区间染色) Horizontally Visible Segments

    这道题做了快两天了.首先就是按照这些竖直线段的横坐标进行从左到右排序. 将线段的端点投影到y轴上,线段树所维护的信息就是y轴区间内被哪条线段所覆盖. 对于一条线段来说,先查询和它能相连的所有线段,并加 ...

  8. ZOJ1610 Count the Colors —— 线段树 区间染色

    题目链接:https://vjudge.net/problem/ZOJ-1610 Painting some colored segments on a line, some previously p ...

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

随机推荐

  1. 常州day1p4

    给定一棵 n 个点的树,树上每个节点代表一个小写字母,询问一个字符串 S 是否在树上出现过? 字符串 S 出现过即表示存在两个点 u,v,u 到 v 的最短路径上依次连接所有点上的字母恰好是 S N ...

  2. 廖大大python学习笔记1

    列表classmates = ['Michael', 'Bob', 'Tracy']classmates.append('tom')print classmates# classmates.inser ...

  3. python打造12306余票实时监控

    # encoding=utf-8from Tkinter import *from ScrolledText import ScrolledTextimport urllib2import jsoni ...

  4. 【agc004C】AND Grid

    Portal --> agc004C Description 给你一个\(n*m\)的网格图\(A\),有一些格子是'#',现在要构造出两个新的网格图\(B\)和\(C\)满足: 1.如果\(A ...

  5. 在Android 下写一个检测软件版本号 以自动升级APP 的插件

    直接上图上代码: 1.插件类的编写 工程目录结构图: 代码如下: package org.apache.cordova.versionupdate; import org.apache.cordova ...

  6. spoj694 DISUBSTR - Distinct Substrings

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  7. Hdu3022 Sum of Digits

    Sum of Digits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  8. signal和sigaction 分析

    1:signal 函数 原型: sighandler_t signal(int signum, sighandler_t handler)      typedef void (*sighandler ...

  9. 题解 P2598 【[ZJOI2009]狼和羊的故事】

    P2598 [ZJOI2009]狼和羊的故事 题目描述 "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听到这首歌,心想:狼 ...

  10. 分块基础练习 UESTC 1324

    http://acm.uestc.edu.cn/#/problem/show/1324 思路:基础分块,这个是一个特别简单的分块,就当做是一个练习了.然后这题也是很简单的单点线段树更新. //看看会不 ...