點選打開連結
利用dfs序将多叉樹映射到線段樹上
對于任意一個節點 在先序序列中每個子節點都在其後 而在後序序列中每個子節點都在其前 這樣就确定了多叉樹的一棵子樹線上段樹中的左右區間
#include <bits/stdc++.h>
using namespace std;
struct node1
{
int l;
int r;
int laz;
int val;
};
struct node2
{
int l;
int r;
};
struct node3
{
int v;
int next;
};
node1 tree[200010];
node2 point[50010];
node3 edge[50010];
int book[50010],first[50010];
int n,q,num;
void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
return;
}
void safari(int u,int fat)
{
int i,v;
point[u].l=num++;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(v!=fat)
{
safari(v,u);
}
}
point[u].r=num-1;
return;
}
void pushdown(int cur)
{
tree[cur*2].laz=tree[cur].laz;
tree[cur*2].val=tree[cur].laz;
tree[cur*2+1].laz=tree[cur].laz;
tree[cur*2+1].val=tree[cur].laz;
tree[cur].laz=-1;
return;
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].laz=-1;
tree[cur].val=-1;
if(l==r) return;
m=(l+r)/2;
build(l,m,cur*2);
build(m+1,r,cur*2+1);
return;
}
int query(int tar,int cur)
{
if(tree[cur].l==tree[cur].r)
{
return tree[cur].val;
}
if(tree[cur].laz>=0) pushdown(cur);
if(tar<=tree[cur*2].r) return query(tar,cur*2);
else return query(tar,cur*2+1);
}
void update(int ll,int rr,int val,int cur)
{
if(ll<=tree[cur].l&&tree[cur].r<=rr)
{
tree[cur].laz=val;
tree[cur].val=val;
return;
}
if(tree[cur].laz>=0) pushdown(cur);
if(ll<=tree[cur*2].r) update(ll,rr,val,cur*2);
if(rr>=tree[cur*2+1].l) update(ll,rr,val,cur*2+1);
return;
}
int main()
{
int t,cas,i,u,v;
char ch[2];
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
memset(book,0,sizeof(book));
memset(first,-1,sizeof(first));
num=0;
for(i=0;i<n-1;i++)
{
scanf("%d%d",&u,&v);
book[u]=1;
addedge(v,u);
}
num=1;
for(i=1;i<=n;i++)
{
if(!book[i])
{
safari(i,-1);
break;
}
}
build(1,n,1);
scanf("%d",&q);
printf("Case #%d:\n",cas);
while(q--)
{
scanf("%s",ch);
if(ch[0]=='C')
{
scanf("%d",&u);
printf("%d\n",query(point[u].l,1));
}
else
{
scanf("%d%d",&u,&v);
update(point[u].l,point[u].r,v,1);
}
}
}
return 0;
}