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

2024-01-03 13:32
文章标签 dfs hdu 线段 task assign 3974

本文主要是介绍HDU 3974 Assign the task (DFS + 线段树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 
加2017新生赛(点击红色的Registerring)

Assign the task

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3816    Accepted Submission(s): 1581


Problem Description
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.

Input
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)

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

Sample Input
      
1 5 4 3 3 2 1 3 5 2 5 C 3 T 2 1C 3 T 3 2 C 3

Sample Output
      
Case #1: -1 1 2


【题意】

给 个树 关系图,   每次 修改和查询,  查询 当前点 的状态,    实质为区间修改 单点查询


【思路】

DFS 先将树的关系 列出, 然后 区间线段树


【代码实现】

//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, rusing namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MAXN=50010;
const int MOD=1e9+7;
const int mod=1e9+7;int add[MAXN<<2],sum[MAXN<<2];
int head[MAXN],flag[MAXN];
int le[MAXN],ri[MAXN];
int cot,key;struct  node
{int v,next;
}edge[MAXN];void init()
{cot=0;mem(head,-1);
}void add_edge(int u,int v)
{edge[cot].v=v;edge[cot].next=head[u];head[u]=cot++;
}void PushDown(int rt)
{if(add[rt]!=-1){sum[rt<<1]=add[rt];sum[rt<<1|1]=add[rt];add[rt<<1]=add[rt];add[rt<<1|1]=add[rt];add[rt]=-1;}
}
void dfs(int rt)
{le[rt]=++key;for(int i=head[rt];i!=-1;i=edge[i].next)dfs(edge[i].v);ri[rt]=key;
}
void build(int rt,int l,int r)
{sum[rt]=add[rt]=-1;if(l==r)return;int mid=(l+r)>>1;build(lson);build(rson);
}
void update(int rt,int l,int r,int L,int R,int C)
{if(L<=l&&R>=r){sum[rt]=C;add[rt]=C;return;}PushDown(rt);int mid=(l+r)>>1;if(L<=mid) 	update(lson,L,R,C);if(R>mid)	update(rson,L,R,C);
}
int query(int rt,int l,int r,int L,int R)
{if(L<=l&&R>=r){return sum[rt];}PushDown(rt);int mid=(l+r)>>1;int ans=0;if(L<=mid) ans+=query(lson,L,R);if(R>mid) ans+=query(rson,L,R);return ans;
}int main()
{int t;int n,m,q,x,y;int cont=0;cin>>t;while(t--){cin>>n;init();mem(flag,0);mem(ri,0);mem(le,0);for(int i=1;i<n;i++){scanf("%d %d",&x,&y);add_edge(y,x);flag[x]=1;}key=0;for(int i=1;i<=n;i++){if(!flag[i]){dfs(i);break;}}build(1,1,key);cin>>m;printf("Case #%d:\n",++cont);while(m--){char op[5];scanf("%s",op);if(op[0]=='C'){scanf("%d",&x);printf("%d\n",query(1,1,key,le[x],le[x]));}else{scanf("%d %d",&x,&y);//printf("%d %d\n",le[x],ri[x]);update(1,1,key,le[x],ri[x],y);}}}return 0;
}

123

这篇关于HDU 3974 Assign the task (DFS + 线段树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/565858

相关文章

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin