[線段樹] Assign the task HDU
https://vjudge.net/problem/22741/origin
依舊是 樹上對各個結點子樹的操作
原題翻譯:
有一家公司有N個員工(從1到N),公司裡每個員工都有一個直接的老闆(除了整個公司的領導)。如果你是某人的直接老闆,那個人就是你的下屬,他的所有下屬也都是你的下屬。如果你是沒有人的老闆,那麼你就沒有下屬,沒有直接老闆的員工就是整個公司的領導,也就是說N個員工構成了一棵樹。公司通常把一些任務分配給一些員工來完成,當一項任務分配給某個人時,他/她會把它分配給他/她的所有下屬,換句話說,這個人和他/她的所有下屬在同一時間接受了一項任務。此外,每當員工收到一個任務,他/她將停止當前任務(如果他/她有),並開始新的任務。在公司將某些任務分配給某個員工後,編寫一個程式來幫助找出某個員工當前的任務。
第一行包含單個正整數T(T<=10),表示測試用例的數量。對於每個測試用例:第一行包含一個整數N(N≤50,000),它是僱員的數目。下面的N-1行分別包含兩個整數u和v,這意味著僱員v是僱員u的直接老闆(1<=u,v<=N)。下一行包含一個整數M(M≤50,000)。下面的M行分別包含一條訊息,“Cx”表示對員工x的當前任務的查詢,“Tx y”表示公司將任務y分配給員工x。(1<=x<=N,0<=y<=10^9)
此時 這題與poj上 apple tree 單點更新不一樣了 任務更新到某個結點 就要讓他的員工都被覆蓋次任務 線段樹的區間更新 補上pushdown 即可
某些 題目沒有給出根節點 只需要知道跟入度為0 用vis把兒子結點全標記 然後for暴力查就好
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <list>
using namespace std;
typedef long long ll;
const int maxe = 1e6+5;
const int maxv = 50000+100;
const int maxn = 50000+100;
const int mod = 1000000 ;
const int INF = 0x3f3f3f3f;
const double PI=acos(-1.0);
const int cx[]={0,0,1,-1};
const int cy[]={1,-1,0,0};
int t,n,m,st,ed;
int tree[maxn<<2],add[maxn<<2];
int nxt[maxn],head[maxn],ver[maxn];
int cnt,id;
bool vis[maxn];
struct node{
int l,r;
}point[maxn];
void add_e(int u,int v){
nxt[++cnt]=head[u];
ver[cnt]=v;
head[u]=cnt;
}
void dfs(int x){
point[x].l=++id;
for(int i=head[x];i!=-1;i=nxt[i]){
dfs(ver[i]);
}
point[x].r=id;
}
void pushdown(int rt){
add[rt<<1]=add[rt<<1|1]=add[rt];
tree[rt]=tree[rt<<1]=tree[rt<<1|1]=add[rt];
add[rt]=-1;
}
void updata(int L,int R,int l,int r,int rt,int c){
if(L<=l&&R>=r){
add[rt]=c;
tree[rt]=c;
return ;
}
if(add[rt]!=-1) pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid) updata(L,R,l,mid,rt<<1,c);
if(R>mid) updata(L,R,mid+1,r,rt<<1|1,c);
}
int query(int L,int l,int r,int rt){
if(l==r){
return tree[rt];
}
if(add[rt]!=-1) pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid) query(L,l,mid,rt<<1);
else query(L,mid+1,r,rt<<1|1);
}
int main(){
scanf("%d",&t);
int cas=1;
while(t--){
printf("Case #%d:\n",cas++);
cnt=-1;id=0;
memset(vis,0,sizeof(vis));
memset(nxt,-1,sizeof(nxt));
memset(head,-1,sizeof(head));
memset(tree,-1,sizeof(tree));
memset(add,-1,sizeof(add));
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d %d",&st,&ed);
vis[st]=1;
add_e(ed,st);
}
for(int i=1;i<=n;i++)
if(!vis[i]) dfs(i);
char ch;
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf(" %c %d",&ch,&st);
if(ch=='C'){
// cout<<point[st].l<<" "<<point[st].r<<endl;
printf("%d\n",query(point[st].l,1,n,1));
}
else{
scanf("%d",&ed);
// cout<<point[st].l<<" "<<point[st].r<<endl;
updata(point[st].l,point[st].r,1,n,1,ed);
}
}
}
return 0;
}
相關推薦
[線段樹] Assign the task HDU
https://vjudge.net/problem/22741/origin 依舊是 樹上對各個結點子樹的操作 原題翻譯: 有一家公司有N個員工(從1到N),公司裡每個員工都有一個直接的老闆(除了整個公司的領導)。如果你是某人的直接老闆,那個人就是你的下屬,他
J - Assign the task HDU - 3974(線段樹 + dfs序)
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 compa
Assign the task HDU
按照dfs序建樹,區間更新點查詢 #include<iostream> #include<stdio.h> #include<cstring> using namespace std; #define maxn 50020
HDU 3974 Assign the task(線段樹 時間戳)
truct stream char %d 節點 正在 原因 scanf 全部 題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3974 題意:n名員工組成一棵樹,分配任務給其中一名員工,那麽他和他的手下(就是該節點
HDU 3974 Assign the task(DFS序+線段樹)
string ssi 組成 ase target 區間 兩張 img lan 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 題意:n名員工組成一棵樹,分配任務給其中一名員工,那麽他和他的手下(就是該節點的全部子節點
HDU - 3974 Assign the task (線段樹區間修改+構建模型)
add algorithm als struct 它的 stream time ons pda https://cn.vjudge.net/problem/HDU-3974 題意 有一棵樹,給一個結點分配任務時,其子樹的所有結點都能接受到此任務。有兩個操作,C x表示查
HDU 3974 Assign the task—— 線段樹樹狀儲存
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 c
HDU 3974 Assign the task(線段樹+dfs序)
題意: 一棵樹的結構,父節點是老闆,子節點是員工,每次給父節點分配的任務,立即會下分到他所有的子節點,有更新和查詢命令。 分析: 採用dfs序進行建樹,可以很好的對區間進行修改和查詢。 #include<bits/stdc++.h> using name
HDU 3974 Assign the task(dfs時間戳+線段樹成段更新)
題意:給定點的上下級關係,規定如果給i分配任務a,那麼他的所有下屬。都停下手上的工作,開始做a。 操作 T x y 分配x任務y,C x詢問x的當前任務; Sample Input 1 5 4 3 3 2 1 3 5 2 5 C
HDU3974 Assign the task(多叉樹轉換為線段+線段樹區間染色)
結束 turn amp cas truct 沒有 遍歷 || 們的 題目大意:有n個人,給你他們的關系(老板和員工),沒有直屬上司的人就是整個公司的領導者,這意味著n個人形成一棵樹(多叉樹)。當一個人被分配工作時他會讓他的下屬也做同樣的工作(並且立即停止手頭正在做的工作),
HDU3974 Assign the task —— dfs時間戳 + 線段樹
media close you void iat gns can for each ack 題目鏈接:https://vjudge.net/problem/HDU-3974 There is a company that has N employees(numbered
hdu3974 Assign the task線段樹 dfs序
題意: 無序的給編號為1-n的員工安排上下級, 操作一:給一個員工任務C,則該員工以及他的下級任務都更換為任務C 操作二:詢問一個員工,返回他的任務 題解: 給一個員工任務,則他所在組都要改變,聯想到線段樹的區間修改,但是這裡是對一個人操作,不是區間操作,如果能把“點”操
HDU 3974 Assign the task
開始時間 set sizeof 代碼 task spa 以及 show 靜態 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 解題思路:深搜設置時間戳,然後線段樹上更新查詢即可。 第一次寫,還算順利(盡管wa了兩發)。
HDU 3947 Assign the task
employee rom san uil single all exce ron %d http://acm.hdu.edu.cn/showproblem.php?pid=3974 Problem Description There is a company th
【線段樹優化DP】 HDU 3698 Let the light guide us
ans build tchar bit txt 。。 bre hellip har 這篇博客主要是發現了…… #define cmin(x,y) (x>y?x=y:0) 要比 void cmin(int &x,int y){i
當前插入的線段能完整覆蓋存在的幾條線段 樹狀數組 HDU 5372 Segment Game
刪除 som normal 時間 time ace others ram uniq http://acm.hdu.edu.cn/showproblem.php?pid=5372 Segment Game Time Limit: 3000/1500 MS
HDOJ 3974 Assign the task
efi cmd read lba -c -m 題意 兩種 min 題意 給定一棵多叉樹,每個節點定義val,job ,指定val,初始job全為 -1 兩種操作 C x :查詢結點val==x的job值 T x y 將以val == x為根節點的子樹的所有節點的job值改
J - Assign the task
printf .net con std query ram borde size style J - Assign the task HDU - 3974 思路:一眼秒思路<(* ̄▽ ̄*)/ dfs序+線段樹。 通過dfs序把樹上問題轉化成
HDU3974 Assign the task
dia pac print more key size class bottom problem Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (
kuangbin專題七 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 immediate boss (except for the leader of whole company)