题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974

给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操作:

有两种操作:

  操作一:T X Y ,将以X为根的子树上的所有节点都变成Y。

  操作二:C X,查询第X号点是多少?

没想到是线段树做,就算想到了也想不到用dfs序做...

例子中给你了这样的树:

   2

/     \

3       5

/    \

4      1

DFS一遍转化成DFS序:2344113552

然后记录下每个数字最左边和最右边的位置,如:left[3] = 2,  right[3] = 7。

因为是DFS序,所以他的子节点的范围一定包含在他的左右位置中。

所以就变成了很明显的线段树成段更新...

注意一点的是,查询是单点更新...

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e5 + ;
const int INF = 1e9 + ;
struct segtree {
int l , r , val , lazy;
}T[MAXN << ];
struct data {
int next , to;
}edge[MAXN];
int head[MAXN] , cont , L[MAXN] , R[MAXN];
//链式前向星
inline void add(int u , int v) {
edge[cont].to = v;
edge[cont].next = head[u];
head[u] = cont++;
}
//DFS序
void dfs(int u) {
L[u] = min(L[u] , ++cont);
R[u] = max(R[u] , cont);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
dfs(v);
}
L[u] = min(L[u] , ++cont);
R[u] = max(R[u] , cont);
} void init(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r , T[p].lazy = ;
if(l == r) {
T[p].val = -;
return ;
}
init(p << , l , mid);
init((p << )| , mid + , r);
} void updata(int p , int l , int r , int val) {
int mid = (T[p].l + T[p].r) >> ;
if(l == T[p].l && T[p].r == r) {
T[p].val = val;
T[p].lazy = val;
return ;
}
if(T[p].lazy) {
T[p << ].val = T[(p << )|].val = T[p << ].lazy = T[(p << )|].lazy = T[p].lazy;
T[p].lazy = ;
}
if(r <= mid) {
updata(p << , l , r , val);
}
else if(l > mid) {
updata((p << )| , l , r , val);
}
else {
updata(p << , l , mid , val);
updata((p << )| , mid + , r , val);
}
} int query(int p , int index) {
int mid = (T[p].l + T[p].r) >> ;
if(index == T[p].l && T[p].r == index) {
return T[p].val;
}
if(T[p].lazy) {
T[p << ].val = T[(p << )|].val = T[p << ].lazy = T[(p << )|].lazy = T[p].lazy;
T[p].lazy = ;
}
if(index <= mid) {
return query(p << , index);
}
else {
return query((p << )| , index);
}
} int main()
{
int t , n , u , v , root , q;
char str[];
scanf("%d" , &t);
for(int ca = ; ca <= t ; ca++) {
scanf("%d" , &n);
cont = , root = (n + ) * n / ;
for(int i = ; i <= n ; i++) {
R[i] = head[i] = -;
L[i] = INF;
}
for(int i = ; i < n ; i++) {
scanf("%d %d" , &u , &v);
root -= u;
add(v , u);
}
cont = ;
dfs(root);
init( , , cont);
printf("Case #%d:\n" , ca);
scanf("%d" , &q);
while(q--) {
scanf("%s" , str);
if(str[] == 'T') {
scanf("%d %d" , &u , &v);
updata( , L[u] , R[u] , v);
}
else {
scanf("%d" , &u);
printf("%d\n" , query( , L[u]));
}
}
}
}

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. [Assign the task][dfs序+线段树]

    http://acm.hdu.edu.cn/showproblem.php?pid=3974 Assign the task Time Limit: 15000/5000 MS (Java/Other ...

  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: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

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

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

  7. HDU3974 Assign the task —— dfs时间戳 + 线段树

    题目链接:https://vjudge.net/problem/HDU-3974 There is a company that has N employees(numbered from 1 to ...

  8. Assign the task-HDU3974 dfs序+线段树

    题意: 一个公司有n个员工,每个员工都有一个上司,一个人下属的下属也是这个人的下属,因此可将他们的关系看成一棵树, 然后给定两种操作,C操作是查询当前员工的工作,T操作是将y工作分配给x员工,当一个人 ...

  9. HDU 5692 Snacks bfs版本dfs序 线段树

    Snacks 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5692 Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连 ...

随机推荐

  1. Lambda表达式【转】

    lambda表达式是对匿名方法的一种改进,具有更加简洁的语法和更易理解的形式,lambda表达式可以包括表达式和语句,并且可以用与创建委托或表达式目录树类型. lambda表达式都使用Lambda运算 ...

  2. Asp.net正则获取html内容

    1.获取div内容 string str = "tt<u>ss</u><div id=\"test\"><div>< ...

  3. I.MX6 git patch

    /********************************************************************** * I.MX6 git patch * 说明: * 之前 ...

  4. HDU 3746 Cyclic Nacklace 环形项链(KMP,循环节)

    题意: 给一个字符串,问:要补多少个字符才能让其出现循环?出现循环是指循环节与字符串长度不相等.比如abc要补多个变成abcabc.若已经循环,输出0. 思路: 根据最小循环节的公式,当len%(le ...

  5. 物联网操作系统HelloX应用编程指南

    HelloX操作系统应用编程指南 HelloX应用开发概述 可以通过三种方式,在HelloX操作系统基础上开发应用: 1.        以内部命令方式实现应用,直接编译链接到HelloX的内核she ...

  6. CXF之六 自定义拦截器

    CXF已经内置了一些拦截器,这些拦截器大部分默认添加到拦截器链中,有些拦截器也可以手动添加,如手动添加CXF提供的日志拦截器.也可以自定义拦截器,CXF中实现自定义拦截器很简单,只要继承Abstrac ...

  7. CXF之七 传输文件

    CXF的文件传输通过MTOM实现.MTOM(SOAP Message Transmission Optimization Mechanism)SOAP消息传输优化机制,可以在SOAP消息中发送二进制数 ...

  8. Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...

  9. PICT实现组合测试用例(一)

    最近阅读了史亮老师的<软件测试实战:微软技术专家经验总结>一书,其中“测试建模”一章让我受益匪浅.想想以前的测试有多久没有花过心思放在测试用例的设计上了,一直强调“测试思想”的培养也都只是 ...

  10. 《Python基础教程(第二版)》学习笔记 -> 第十章 充电时刻 之 标准库

    SYS sys这个模块让你能够访问与Python解释器联系紧密的变量和函数,下面是一些sys模块中重要的函数和变量: 函数和变量 描述 argv 命令行参数,包括脚本和名称 exit([arg])   ...