HDU4008 Parent and son - dfs序/bfs序 - 线段树

传送门

题解:换根操作是老套路,这个有一问是求儿子中的信息,要用bfs序来维护;

要注意的是要求儿子的bfs序和本身并不是连续的。

代码:

#include
#include
#include
#include
#include
#define MAXN 100010
#define MAXM 200010
#define MAXL 20
#define INF (MAXN-2)
#define debug(x) cerr<<#x<<"="< q;
inline int bfs(int s)
{
    while(!q.empty()) q.pop();
    bin[s]=++bfs_clock;
    q.push(s);btimes[bfs_clock]=s;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=h[x];i;i=e[i].pre)
            if(e[i].to^fa[x])
            {
                bin[e[i].to]=++bfs_clock;
                L[x]=min(L[x],bfs_clock);
                R[x]=max(R[x],bfs_clock);
                son[x]++;btimes[bfs_clock]=e[i].to;q.push(e[i].to);
            }
    }
    return 0;
}
inline int getlx(int x,int y)
{
    for(int i=MAXL-1;i>=0;i--)
        if(dep[up[x][i]]>dep[y])
            x=up[x][i];
    return x;
}
struct segment{
    int l,r,minn,rm;
    segment *ch[2];
}*brt,*rt,pool[MAXN<<2];int pool_top;
inline int push_up(segment* &rt)
{
    rt->minn=min(rt->ch[0]->minn,rt->ch[1]->minn);
    rt->rm=min(rt->ch[0]->rm,rt->ch[1]->rm);
    return 0;
}
inline int build(segment* &rt,int l,int r,int k)
{
    rt=&pool[++pool_top];
    rt->l=l;rt->r=r;
    rt->ch[0]=rt->ch[1]=NULL;
    if(l==r) return rt->minn=rt->rm=(k?times[l]:btimes[r]);
    int mid=(l+r)>>1;
    build(rt->ch[0],l,mid,k);
    build(rt->ch[1],mid+1,r,k);
    push_up(rt);return 0;
}
inline int update(segment* &rt,int s,int t,int v)
{
    int l=rt->l,r=rt->r;
    if(s<=l&&r<=t) return (v^INF)?(rt->minn=rt->rm):(rt->minn=v);
    int mid=(l+r)>>1;
    if(s<=mid) update(rt->ch[0],s,t,v);
    if(midch[1],s,t,v);
    push_up(rt);return 0;
}
inline int query(segment* &rt,int s,int t)
{
    if(s>t) return INF;
    int l=rt->l,r=rt->r;
    if(s<=l&&r<=t) return rt->minn;
    int mid=(l+r)>>1,ans=INF;
    if(s<=mid) ans=min(ans,query(rt->ch[0],s,t));
    if(midch[1],s,t));
    push_up(rt);return ans;
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n,q;scanf("%d%d",&n,&q);
        memset(h,0,sizeof(h)),etop=0;
        for(int i=1;i


你可能感兴趣的:(线段树)