题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974
题意:n名员工组成一棵树,分配任务给其中一名员工,那么他和他的手下(就是该节点的全部子节点们)就要开始做这项任务,询问其中一个员工
输出他正在进行任务
题解:题目给我们的是两两员工的关系(其中一个是另一个的上司),整一个树。因为数据原因,用线段树去实现,要形成区间,这时候我们可以用dfs
给每个员工打上时间戳,形成区间代表最前面的那个上司统领员工(区间长度表示统领的员工数),然后就可以用线段树去处理。(下面两张图很好的解释了DFS序的作用)
1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 const int N=50010; 9 10 int st[N],en[N]; 11 int index; 12 bool used[N]; 13 vector <int> E[N]; 14 15 void dfs(int k){ 16 st[k]=++index; 17 int len=E[k].size(); 18 for(int i=0;i<len;i++) dfs(E[k][i]); 19 en[k]=index; 20 } 21 22 struct Tree 23 { 24 int l,r,task; 25 bool vis; 26 }; 27 Tree tree[4*N]; 28 29 void pushdown(int x) 30 { 31 int tmp=x<<1; 32 if(tree[x].l!=tree[x].r){ 33 tree[tmp].vis=tree[tmp+1].vis=1; 34 tree[tmp].task=tree[tmp+1].task=tree[x].task; 35 tree[x].vis=0; 36 } 37 } 38 39 void build(int l,int r,int x) 40 { 41 tree[x].l=l;tree[x].r=r; 42 tree[x].task=-1;tree[x].vis=0; 43 if(l==r) return ; 44 int tmp=x<<1; 45 int mid=(l+r)>>1; 46 build(l,mid,tmp); 47 build(mid+1,r,tmp+1); 48 } 49 50 void update(int l,int r,int c,int x) 51 { 52 if(r<tree[x].l||l>tree[x].r) return ; 53 if(l==tree[x].l&&r==tree[x].r) 54 { 55 tree[x].task=c; 56 tree[x].vis=1; 57 return ; 58 } 59 if(tree[x].vis) pushdown(x); 60 int tmp=x<<1; 61 int mid=(tree[x].l+tree[x].r)>>1; 62 if(r<=mid) update(l,r,c,tmp); 63 else if(l>mid) update(l,r,c,tmp+1); 64 else 65 { 66 update(l,mid,c,tmp); 67 update(mid+1,r,c,tmp+1); 68 } 69 } 70 71 int query(int k,int x) 72 { 73 if(k==tree[x].l&&k==tree[x].r) return tree[x].task; 74 if(tree[x].vis) pushdown(x); 75 int tmp=x<<1; 76 int mid=(tree[x].l+tree[x].r)>>1; 77 if(k<=mid) query(k,tmp); 78 else if(k>mid) query(k,tmp+1); 79 } 80 81 int main(){ 82 int t,n,u,v,m,Case=1; 83 char op[10]; 84 scanf("%d",&t); 85 while(t--){ 86 memset(used,0,sizeof(used)); 87 scanf("%d",&n); 88 for(int i=1;i<=n;i++) E[i].clear(); 89 for(int i=1;i<n;i++){ 90 scanf("%d%d",&u,&v); 91 E[v].push_back(u); 92 used[u]=1; 93 } 94 index=0; 95 for(int i=1;i<=n;i++){ 96 if(!used[i]) {dfs(i);break;} 97 } 98 printf("Case #%d:\n",Case++); 99 build(1,n,1); 100 scanf("%d",&m); 101 while(m--){ 102 scanf("%s",op); 103 if(op[0]==‘C‘){ 104 scanf("%d",&u); 105 printf("%d\n",query(st[u],1)); 106 } 107 else if(op[0]==‘T‘){ 108 scanf("%d%d",&u,&v); 109 update(st[u],en[u],v,1); 110 } 111 } 112 } 113 return 0; 114 }