HDU 3974 Assign the task 暴力/线段树
题目链接:
题目
Assign the task
Time Limit: 15000/5000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
问题描述
There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the leader of whole company).If you are the immediate boss of someone,that person is your subordinate, and all his subordinates are your subordinates as well. If you are nobody's boss, then you have no subordinates,the employee who has no immediate boss is the leader of whole company.So it means the N employees form a tree.
The company usually assigns some tasks to some employees to finish.When a task is assigned to someone,He/She will assigned it to all his/her subordinates.In other words,the person and all his/her subordinates received a task in the same time. Furthermore,whenever a employee received a task,he/she will stop the current task(if he/she has) and start the new one.
Write a program that will help in figuring out some employee’s current task after the company assign some tasks to some employee.
输入
The first line contains a single positive integer T( T <= 10 ), indicates the number of test cases.
For each test case:
The first line contains an integer N (N ≤ 50,000) , which is the number of the employees.
The following N - 1 lines each contain two integers u and v, which means the employee v is the immediate boss of employee u(1<=u,v<=N).
The next line contains an integer M (M ≤ 50,000).
The following M lines each contain a message which is either
"C x" which means an inquiry for the current task of employee x
or
"T x y"which means the company assign task y to employee x.
(1<=x<=N,0<=y<=10^9)
输出
For each test case, print the test case number (beginning with 1) in the first line and then for every inquiry, output the correspond answer per line.
样例
input
1
5
4 3
3 2
1 3
5 2
5
C 3
T 2 1
C 3
T 3 2
C 3
output
Case #1:
-1
1
2
题意
给你一颗树,执行两种操作:
把以x为根的子树的任务全部赋值为y.
查询x的当前任务。
题解
查了很多题解说是并查集,明明赤裸裸的暴力,看不出哪里跟并查集有关。。
暴力为什么能过orz,想都没敢想暴力。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 5e4 + 10;
int fa[maxn], tim[maxn], tas[maxn];
int n,tot=0;
void init() {
tot = 0;
memset(tim, 0, sizeof(tim));
memset(fa, -1, sizeof(fa));
memset(tas, -1, sizeof(tas));
}
int main() {
int tc, kase = 0;
scanf("%d", &tc);
while (tc--) {
scanf("%d", &n);
init();
for (int i = 0; i < n - 1;i++){
int u, v;
scanf("%d%d", &u, &v);
fa[u] = v;
}
int q;
scanf("%d", &q);
printf("Case #%d:\n", ++kase);
while (q--) {
char cmd[11]; int x, y;
scanf("%s", cmd);
if (cmd[0] == 'C') {
scanf("%d", &x);
int t = -1, v = -1;
while (x != -1) {
if (t < tim[x]) {
t = tim[x];
v = tas[x];
}
x = fa[x];
}
printf("%d\n", v);
}else{
scanf("%d%d", &x, &y);
tim[x] = ++tot;
tas[x] = y;
}
}
}
return 0;
}
还是感觉来一发线段树比较靠谱。
求dfs序,按照这个序来建线段树。
时间跑的竟然还不如暴力orz。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define lson (o<<1)
#define rson ((o<<1)|1)
#define M (l+(r-l)/2)
using namespace std;
const int maxn = 5e4 + 10;
int n;
int fa[maxn],pre[maxn], aft[maxn], dfs_clock;
vector<int> G[maxn];
void dfs(int u) {
pre[u] = ++dfs_clock;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == fa[u]) continue;
dfs(v);
}
aft[u] = ++dfs_clock;
}
int setv[maxn << 3], timv[maxn << 3],tot;
int _p, _ret,_tim;
void query(int o, int l, int r) {
if (l == r) {
if (_tim < timv[o]) {
_tim = timv[o], _ret = setv[o];
}
}
else {
if (_tim < timv[o]) {
_tim = timv[o], _ret = setv[o];
}
if (_p <= M) query(lson, l, M);
else query(rson, M + 1, r);
}
}
int ul, ur, uv,ut;
void update(int o, int l, int r) {
if (ul <= l&&r <= ur) {
setv[o] = uv, timv[o] = ut;
}
else {
if(ul<=M) update(lson, l, M);
if(ur>M) update(rson, M + 1, r);
}
}
void init() {
dfs_clock = tot = 0;
for (int i = 0; i <= n; i++) G[i].clear();
memset(setv, -1, sizeof(setv));
memset(timv, -1, sizeof(timv));
memset(fa, -1, sizeof(fa));
}
int main() {
int tc, kase = 0;
scanf("%d", &tc);
while (tc--) {
scanf("%d", &n);
init();
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
G[v].push_back(u);
fa[u] = v;
}
int rt = -1;
for (int i = 1; i <= n; i++) if (fa[i] == -1) {
rt = i; break;
}
dfs(rt);
int q;
scanf("%d", &q);
printf("Case #%d:\n", ++kase);
while(q--){
char cmd[22]; int x, y;
scanf("%s", cmd);
if (cmd[0] == 'C') {
scanf("%d", &x);
_p = pre[x], _ret = -1, _tim = -1;
query(1, 1, dfs_clock);
printf("%d\n", _ret);
}
else {
scanf("%d%d", &x, &y);
ul = pre[x], ur = aft[x],uv=y,ut=++tot;
update(1, 1, dfs_clock);
}
}
}
return 0;
}
HDU 3974 Assign the task 暴力/线段树的更多相关文章
- hdu 3974 Assign the task(线段树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3974 题意:给定一棵树,50000个节点,50000个操作,C x表示查询x节点的值,T x y表示更 ...
- HDU - 3974 Assign the task (线段树区间修改+构建模型)
https://cn.vjudge.net/problem/HDU-3974 题意 有一棵树,给一个结点分配任务时,其子树的所有结点都能接受到此任务.有两个操作,C x表示查询x结点此时任务编号,T ...
- HDU 3974 Assign the task (DFS+线段树)
题意:给定一棵树的公司职员管理图,有两种操作, 第一种是 T x y,把 x 及员工都变成 y, 第二种是 C x 询问 x 当前的数. 析:先把该树用dfs遍历,形成一个序列,然后再用线段树进行维护 ...
- hdu 3974 Assign the task (线段树+树的遍历)
Description There is a company that has N employees(numbered from 1 to N),every employee in the comp ...
- HDU 3974 Assign the task 并查集/图论/线段树
Assign the task Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- HDU 3974 Assign the task (DFS序 + 线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操 ...
- 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 ...
- HDU 3974 Assign the task(简单线段树)
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3974 Assign the task(dfs序上线段树)
Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...
随机推荐
- Python调用Webservice、访问网页
昨天在调试Webservice的时候,由于不想写测试程序,就想用Python访问Webservice,结果还是相当的麻烦.远没有VSIDE用的方便 不得不说VS还是很强大的,人性化做的很好,不需要你看 ...
- Linux命令(2):ls命令
1.作用:列出目录的内容: 2.格式:ls [选项] [文件] [选项]为指定要查看文件相关的内容,若未指定文件默认查看当前目录下的所有文件: 3.常见参数: 如图: 4.使用实例: [yournam ...
- 20141104--SQL连接查询,联合查询
---------------------------连接查询-------------------------------- --横向连接查询 --可以将子查询放在from之前,用来替换显示出来的信 ...
- (转)MongoDB 3.0 WT引擎参考配置文件
mongodb 3.0 改变很多,从2.6版本升级到3.0要关注的细节很多,如权限等等.3.0在数据存储引擎上更换成了wiredTiger,在数据压缩方面很有效,解决大数据量问题的情况下,磁盘不够用的 ...
- 杭电ACM2076--夹角有多大(题目已修改,注意读题)
杭电ACM2076--夹角有多大(题目已修改,注意读题) http://acm.hdu.edu.cn/showproblem.php?pid=2076 思路很简单.直接贴代码.过程分析有点耗时间. / ...
- void指针
指针有两个属性:指向变量/对象的地址 和长度 但是指针只存储地址,长度则取决于指针的类型 编译器根据指针的类型从指针指向的地址向后寻址 指针类型不同则寻址范围也不同,比如: int*从指定地址向后寻找 ...
- ARC小知识
ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting).简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管 ...
- C语言求两个函数中的较大者的MAX函数
//求两个函数中的较大者的MAX函数 #include <stdio.h> int main(int argc, const char * argv[]) { printf("i ...
- EF6数据迁移
当Moldes发生改变时 会提示数据上下文的模型已在数据库创建后发生改变,则需要重建数据库并数据迁移 在NuGet程序包管理控制台输入enable-migrations启用数据迁移 之后会提示&quo ...
- request.getSession();为什么不用response儿用request!
首先回答为什么分别是response和request这两个内置对象.你得先明白你通过获取对象是做什么用的,是往哪用的.第一个PrintWriter out=response.getWriter()是想 ...