题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3974
题意:
给你一个树,v,u 表示u是v的上司
有两个操作
1.让某一个点,和他的儿子们全部染成X
2.查询某一个点是什么颜色
题解:
当成图论跑一发,对于每一个查询直接跑到根位置就好,更新的时候,注意更新的时间问题
线段树也可以做:
将树映射到区间的线段树。。。
主要是将原有的关系树根据BOSS关系从新编号,
以便把每个BOSS所带领的员工全部压入一个连续区间内,
然后记录每个BOSS的起始编号和他的最后一名的员工的编号,
然后用线段树区间更新,单点查找即可。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 1e5+10; 17 18 struct node{ 19 int col,t; 20 }a[maxn]; 21 22 int fa[maxn]; 23 24 int main(){ 25 int T = read(); 26 for(int cas=1; cas<=T; cas++){ 27 int n = read(); 28 for(int i=0; i<=n; i++) 29 fa[i] = -1; 30 for(int i=0; i<=n; i++){ 31 a[i].col = a[i].t = -1; 32 } 33 for(int i=1; i<n; i++){ 34 int v,u; scanf("%d%d",&v,&u); 35 fa[v] = u; 36 } 37 int m = read(); 38 printf("Case #%d: ",cas); 39 int t = 0; 40 while(m--){ 41 char op; scanf(" %c",&op); 42 if(op == 'C'){ 43 int u = read(), col = -1, tmp=-1; 44 while(u!=-1){ 45 if(a[u].t > tmp){ 46 col = a[u].col; 47 tmp = a[u].t; 48 } 49 50 u = fa[u]; 51 } 52 printf("%d ",col); 53 }else{ 54 int u=read(), col=read(); 55 a[u].col = col; 56 a[u].t = ++t; 57 } 58 } 59 } 60 61 return 0; 62 }
线段树:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 5e4+10; 17 18 int fa[maxn],cnt; 19 int st[maxn],en[maxn]; 20 vector<int> g[maxn]; 21 22 void dfs(int u,int fa){ 23 st[u] = ++cnt; 24 for(auto v : g[u]){ 25 dfs(v,u); 26 } 27 en[u] = cnt; 28 } 29 30 struct node{ 31 int l,r,col; 32 }tree[maxn<<2]; 33 34 void pushdown(int rt){ 35 if(tree[rt].col!=-1){ 36 tree[rt<<1].col = tree[rt<<1|1].col = tree[rt].col; 37 tree[rt].col = -1; 38 } 39 } 40 41 void build(int rt,int l,int r){ 42 tree[rt].l = l, tree[rt].r = r; 43 tree[rt].col = -1; 44 if(l != r){ 45 int mid = (l+r)/2; 46 build(rt<<1,l,mid); 47 build(rt<<1|1,mid+1,r); 48 } 49 } 50 51 void update(int rt,int l,int r,int val){ 52 int L = tree[rt].l, R = tree[rt].r; 53 if(l<=L && R<=r){ 54 tree[rt].col = val; 55 return ; 56 } 57 pushdown(rt); 58 int mid = (L+R)/2; 59 if(l <= mid) update(rt<<1,l,r,val); 60 if(r > mid) update(rt<<1|1,l,r,val); 61 } 62 63 int query(int rt,int p){ 64 int L = tree[rt].l, R = tree[rt].r; 65 if(L == R){ 66 return tree[rt].col; 67 } 68 int mid = (L+R)/2; 69 pushdown(rt); 70 if(p <= mid) 71 return query(rt<<1,p); 72 else 73 return query(rt<<1|1,p); 74 } 75 76 int main(){ 77 int T = read(); 78 for(int cas=1; cas<=T; cas++){ 79 printf("Case #%d: ",cas); 80 int n = read(); 81 MS(fa); 82 for(int i=0; i<=n; i++) 83 g[i].clear(); 84 for(int i=1; i<n; i++){ 85 int v=read(),u=read(); 86 fa[v] = u; 87 g[u].push_back(v); 88 } 89 90 cnt = 0; 91 for(int i=1; i<=n; i++){ 92 if(fa[i] == 0){ 93 dfs(i,0); 94 break; 95 } 96 } 97 // cout << "hh " << cnt << endl; 98 build(1,1,n); 99 int m = read(); 100 while(m--){ 101 char op; scanf(" %c",&op); 102 if(op == 'C'){ 103 int u = read(); 104 int ans = query(1,st[u]); 105 printf("%d ",ans); 106 }else{ 107 int u=read(),c=read(); 108 update(1,st[u],en[u],c); 109 } 110 } 111 } 112 113 return 0; 114 }