HDU 3974 Assign the task(線段樹+dfs序)
阿新 • • 發佈:2018-12-16
題意:
一棵樹的結構,父節點是老闆,子節點是員工,每次給父節點分配的任務,立即會下分到他所有的子節點,有更新和查詢命令。
分析:
採用dfs序進行建樹,可以很好的對區間進行修改和查詢。
#include<bits/stdc++.h> using namespace std; const int maxn=5e4+10; vector<int> g[maxn]; struct node{ int val; bool mark; }tree[maxn<<2]; bool vis[maxn]; int st[maxn]; int en[maxn]; int cnt; void dfs(int u){ st[u]=++cnt; for(int i=0;i<g[u].size();i++){ dfs(g[u][i]); } en[u]=cnt; } void build(int l,int r,int i){ tree[i].val=-1; tree[i].mark=0; if(l==r){ return; } int mid=l+r>>1; build(l,mid,i<<1); build(mid+1,r,i<<1|1); } inline void update(int i){ if(!tree[i].mark) return; tree[i<<1].mark=tree[i<<1|1].mark=tree[i].mark; tree[i<<1].val=tree[i<<1|1].val=tree[i].val; tree[i].mark=0; } int query(int l,int r,int i,int t){ update(i); if(l==r) return tree[i].val; int mid=l+r>>1; if(t<=mid) return query(l,mid,i<<1,t); else return query(mid+1,r,i<<1|1,t); } void change(int tl,int tr,int l,int r,int i,int val){ if(tl>r||tr<l) return; if(tl<=l&&r<=tr){ tree[i].val=val; tree[i].mark=1; return; } update(i); int mid=l+r>>1; change(tl,tr,l,mid,i<<1,val); change(tl,tr,mid+1,r,i<<1|1,val); } int main(){ int T; scanf("%d",&T); for(int cs=1;cs<=T;cs++){ printf("Case #%d:\n",cs); int n,m; scanf("%d",&n); memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) g[i].clear(); memset(tree,0,sizeof tree); memset(st,0,sizeof st); memset(en,0,sizeof en); cnt=0; for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); g[v].push_back(u); vis[u]=1; } for(int i=1;i<=n;i++){ if(!vis[i]){ dfs(i); break; } } build(1,cnt,1); scanf("%d",&m); while(m--){ char ch; int x,y; scanf(" %c",&ch); if(ch=='C'){ scanf("%d",&x); printf("%d\n",query(1,cnt,1,st[x])); }else{ scanf("%d%d",&x,&y); change(st[x],en[x],1,cnt,1,y); } } } return 0; }