第一次听见这东西。真神奇。
题意:给出一颗n个节点的有向树,根为boss。然后m个操作,T a b表示把a及其管理的员工的工作换成b,C a则为查询a 的工作是什么。
思路:可以先从树根dfs并为节点按照访问顺序编号,那么可以得到每个点能控制的员工访问(包括自身和控制的员工),相当于线段树里面某节点的覆盖区间。其他的按照线段树的正常操作即可
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 50050;
struct node{
int l, r, x;
}tr[N << 2];
struct pp{
int l, r;
}p[N];
vector<int> v[N];
bool oout[N];
int n, m;
int cnt;
void init()
{
for( int i = 1; i <= n; i++ )
v[i].clear();
memset( oout, 0, sizeof( oout ) );
cnt = 0;
}
void dfs( int u )
{
cnt++;
p[u].l = cnt;
int siz = v[u].size();
for( int i = 0; i < siz; ++i )
dfs( v[u][i] );
p[u].r = cnt;
}
void build( int l, int r, int rt )
{
tr[rt].l = l;
tr[rt].r = r;
tr[rt].x = -1;
if( l == r )
return;
int mid = ( l + r ) >> 1;
build( lson );
build( rson );
}
void down( int rt )
{
if( tr[rt].x == -1 )
return;
tr[rt<<1].x = tr[rt<<1|1].x = tr[rt].x;
tr[rt].x = -1;
}
void update( int l, int r, int x, int rt )
{
if( l <= tr[rt].l && tr[rt].r <= r )
{
tr[rt].x = x;
return;
}
down( rt );
int mid = ( tr[rt].l + tr[rt].r ) >> 1;
if( r <= mid )
update( l, r, x, rt << 1 );
else if( l > mid )
update( l, r, x, rt << 1 | 1 );
else
{
update( l, mid, x, rt << 1 );
update( mid+1, r, x, rt << 1 | 1 );
}
}
int query( int pos, int rt )
{
if( tr[rt].x > -1 || tr[rt].l == tr[rt].r )
return tr[rt].x;
down( rt );
int mid = ( tr[rt].l + tr[rt].r ) >> 1;
if( pos <= mid )
return query( pos, rt << 1 );
else
return query( pos, rt << 1 | 1 );
}
int main()
{
int tot, cas = 1;
scanf("%d", &tot);
while( tot-- )
{
int u, to;
char op[2];
init();
scanf("%d", &n);
for( int i = 1; i < n; ++i )
{
scanf("%d%d", &to, &u);
oout[to] = 1;
v[u].push_back( to );
}
for( int i = 1; i <= n; ++i )
if( !oout[i] )
{
dfs( i );
break;
}
build( 1, cnt, 1 );
printf("Case #%d:\n", cas++);
scanf("%d", &m);
while( m-- )
{
scanf("%s", op);
if( op[0] == 'T' )
{
scanf("%d%d", &u, &to);
update( p[u].l, p[u].r, to, 1 );
}
else
{
scanf("%d", &u);
int ans = query( p[u].l, 1 );
printf("%d\n", ans);
}
}
}
return 0;
}