http://acm.hdu.edu.cn/showproblem.php?pid=3974
先把树的dfs序搞出来
然后区间更改
单点查询
很有意思
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int head[N],Next[N],ver[N],B[N],A[N],Begin[N],End[N];
int tot=0;
struct SegmentTree{
int l,r,add,val;
#define l(x) Tree[x].l
#define r(x) Tree[x].r
#define add(x) Tree[x].add
#define val(x) Tree[x].val
}Tree[4*N];
void build(int p,int l,int r){
l(p)=l;r(p)=r;
if(l==r){
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
}
void spread(int p){
if(add(p)){
val(p*2)=add(p);
val(p*2+1)=add(p);
add(p*2+1)=add(p);
add(p*2)=add(p);
add(p)=0;
}
}
void change(int p,int l,int r,int v){
if(l<=l(p)&&r>=r(p)){
val(p)=v;add(p)=v;
return;
}
spread(p);
int mid=(l(p)+r(p))/2;
if(l<=mid) change(p*2,l,r,v);
if(r>mid) change(p*2+1,l,r,v);
}
int ask(int p,int x){
if(l(p)==r(p)){
return val(p);
}
spread(p);
int mid=(l(p)+r(p))/2;
if(x<=mid) return ask(p*2,x);
else return ask(p*2+1,x);
}
void dfs(int x){
A[++tot]=x;
Begin[x]=tot;
for(int i=head[x];i;i=Next[i]){
dfs(ver[i]);
}
A[++tot]=x;
End[x]=tot;
}
int main(){
int n,u,v;
cin>>n;
int flag=0;
while(cin>>n){
cout<<"Case #"<<++flag<<":"<<endl;
tot=0;
memset(ver,0,sizeof ver);
memset(Next,0,sizeof Next);
memset(head,0,sizeof head);
memset(Tree,0,sizeof Tree);
memset(A,0,sizeof A);
memset(B,0,sizeof B);
for(int i=1;i<n;++i){
cin>>u>>v;
ver[i]=u;
Next[i]=head[v];
head[v]=i;
B[u]=1;
}
int root;
for(int i=1;i<=n;++i){
if(B[i]==0) root=i;
}
dfs(root);
build(1,1,2*n);
int m,a,b;
cin>>m;
string s;
while(m--){
cin>>s;
if(s[0]=='C'){
cin>>a;
int ans=ask(1,Begin[a]);
cout<<(ans?ans:-1)<<endl;
}
else{
cin>>a>>b;
change(1,Begin[a],End[a],b);
}
}
}
}
//2553114432