题意:
一个公司里面每个员工都有一个上司,除了一个人没有上司(即老总也就相当于员工),一旦给某个员工分配任务后,这个员工以及其所有下属都在做该任务。
有两个操作,
T:分配给员工任务
C:查询该员工正在执行的任。
题解:看着蛋疼,但是你想成一棵树就可以用DFS序列+线段树来解决问题了,这道题也让我知道我之前的区间判断的写法很不安全,之后将逐渐改成更为正确安全的写法。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
const int MAXN=50000+7;
bool mark[MAXN];
struct Edge
{
int to,next;
}edge[MAXN];
int head[MAXN],tot;
int cnt;
int in[MAXN],out[MAXN];
struct node
{
int l,r;
int lazy,val;
}t[MAXN<<2];
void init()
{
cnt=0;
tot=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs(int u)
{
in[u]=++cnt;
for(int i=head[u];i!=-1;i=edge[i].next)
{
dfs(edge[i].to);
}
out[u]=cnt;
}
void build(int root,int l,int r)
{
t[root].l=l;
t[root].r=r;
t[root].lazy=0;
t[root].val=-1;
if(l==r) return ;
int mid=(l+r)/2;
build(lson);
build(rson);
}
void pushdown(int root)
{
if(t[root].lazy)
{
t[root<<1].lazy=t[root].lazy;
t[root<<1|1].lazy=t[root].lazy;
t[root<<1].val=t[root].lazy;
t[root<<1|1].val=t[root].lazy;
t[root].lazy=0;
}
}
void update(int root,int L,int R,int v)
{
// printf("L=%d R=%d t[root].l=%d t[root].r=%d\n",L,R,t[root].l,t[root].r);
if(t[root].l==L&&t[root].r==R)
{
t[root].val=v;
t[root].lazy=v;
return ;
}
pushdown(root);
int mid=(t[root].l+t[root].r)/2;
// 下面这段WA了,而之前用这种写法不会错,说明这种写法肯定有漏洞,不应该这样写,
// if(L<=mid)
// update(root<<1,L,mid,v);
// if(R>mid)
// update(root<<1|1,mid+1,R,v);
//下面这种写法最安全
if(R <= mid) update(root<<1,L,R,v);
else if(L > mid)update((root<<1)|1,L,R,v);
else
{
update(root<<1,L,mid,v);
update((root<<1)|1,mid+1,R,v);
}
}
int query(int root,int x)
{
if(t[root].l==x&&t[root].r==x)
return t[root].val;
pushdown(root);
int mid=(t[root].l+t[root].r)/2;
if(x<=mid)
query(root<<1,x);
else
query(root<<1|1,x);
}
int main()
{
int T,n,m,i,k=1;
scanf("%d",&T);
while(T--)
{
memset(mark,false,sizeof(mark));
scanf("%d",&n);
int u,v;
init();
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
mark[u]=true;
addedge(v,u);
}
for(i=1;i<=n;i++)
if(!mark[i])
dfs(i);
build(1,1,n);
scanf("%d",&m);
printf("Case #%d:\n",k++);
// for(i=1;i<=n;i++)
// printf("in[%d]=%d out[%d]=%d\n",i,in[i],i,out[i]);
while(m--)
{
char s[2];
int x,y;
scanf("%s",&s);
if(s[0]=='C')
{
scanf("%d",&x);
printf("%d\n",query(1,in[x]));
}
if(s[0]=='T')
{
scanf("%d%d",&x,&y);
update(1,in[x],out[x],y);
}
}
}
}