题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974
这题可以用线段树(区间修改,单点查询)+DFS序(这题里学的,很有意思)或者直接用并查集
线段树+DFS序:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
#define REW(a,b) memset(a,b,sizeof(a))
#define P pair<int,int>
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define pi acos(-1)
#define lc (d<<1)
#define rc (d<<1|1)
int m,n,t,fa[50008],ls[50008],rs[50008],num;
vector<int>g[50008];
struct node{
int l,r,su,lz;}tr[50008<<2];
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
void build(int d,int l,int r)
{
tr[d].l=l,tr[d].r=r,tr[d].su=-1,tr[d].lz=-1;;
if(l==r)
{
return;
}
int mid=(l+r>>1);
build(lc,l,mid);
build(rc,mid+1,r);
return;
}
void dfs(int x)
{
ls[x]=++num;
for(int i=0;i<g[x].size();i++)
{
dfs(g[x][i]);
}
rs[x]=num;
return;
}
void push(int d)
{
if(tr[d].lz>=0)
{
tr[lc].lz=tr[d].lz,tr[rc].lz=tr[d].lz;
tr[lc].su=tr[d].lz,tr[rc].su=tr[d].lz;
tr[d].lz=-1;
}
}
void add(int d,int l,int r,int q)
{
if(tr[d].l==l&&tr[d].r==r)
{
tr[d].su=q;
tr[d].lz=q;
return;
}
push(d);
int mid=(tr[d].l+tr[d].r>>1);
if(r<=mid)
{
add(lc,l,r,q);
}
else if(l>mid)
{
add(rc,l,r,q);
}
else
{
add(lc,l,mid,q),add(rc,mid+1,r,q);
}
return;
}
int query(int d,int x)
{
if(tr[d].l==x&&tr[d].r==x)
{
return tr[d].su;
}
push(d);
int mid=(tr[lc].l+tr[rc].r)>>1;
if(x<=mid)
{
return query(lc,x);
}
else
{
return query(rc,x);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
for(int k=1;k<=t;k++)
{
int n;
cin>>n;
REW(ls,-1);
REW(rs,-1);
for(int i=0;i<=n;i++)
{
fa[i]=i,g[i].clear();
}
int op=n;
num=0;
while(--op)
{
int q,w;
cin>>q>>w;
g[w].push_back(q);
fa[q]=w;
}
for(int i=1;i<=n;i++)
{
if(fa[i]==i)
{
dfs(i);
break;
}
}
build(1,1,n);
int m,s=0;
cin>>m;
cout<<"Case #"<<k<<":"<<endl;
while(m--)
{
string c;
cin>>c;
if(c=="T")
{
int x,y;
cin>>x>>y;
add(1,ls[x],rs[x],y);
}
else if(c=="C")
{
int x;
cin>>x;
cout<<query(1,ls[x])<<endl;
}
}
}
return 0;
}
并查集:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define P pair<int,int>
#define pi acos(-1)
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
int fa[50008],a[50008],b[50008];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
for(int k=1;k<=t;k++)
{
int n;
cin>>n;
REW(a,-1);
REW(b,-1);
for(int i=0;i<=n;i++)
{
fa[i]=i;
}
while(--n)
{
int q,w;
cin>>q>>w;
fa[q]=w;
}
int m,s=0;
cin>>m;
cout<<"Case #"<<k<<":"<<endl;
while(m--)
{
string c;
cin>>c;
if(c=="T")
{
int x,y;
cin>>x>>y;
a[x]=y;
b[x]=s++;
}
else if(c=="C")
{
int x,z,y;
cin>>x;
z=a[x];
y=b[x];
while(fa[x]!=x)
{
if(b[fa[x]]>y)
{
z=a[fa[x]];
y=b[fa[x]];
}
x=fa[x];
}
cout<<z<<endl;
}
}
}
return 0;
}