1. 程式人生 > >HDU 3974 Assign the task(線段樹 時間戳)

HDU 3974 Assign the task(線段樹 時間戳)

truct stream char %d 節點 正在 原因 scanf 全部

題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3974

題意:n名員工組成一棵樹,分配任務給其中一名員工,那麽他和他的手下(就是該節點的全部子節點們)就要開始做這項任務,詢問其中一個員工

輸出他正在進行任務

題解:題目給我們的是兩兩員工的關系(其中一個是另一個的上司),整一個樹。因為數據原因,用線段樹去實現,要形成區間,這時候我們可以用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 }

HDU 3974 Assign the task(線段樹 時間戳)