码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2588 counting on a tree

时间:2018-09-04 01:40:40      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:tin   query   insert   lca   color   def   cst   pre   ==   

题目不难,树上可持久化数据结构。

帖代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 1000005

int n,m,hed[N],cnt,mx;
struct ED
{
    int to,nxt;
}e[2*N];
struct ND
{
    int x,id;
}nd[N];
int to[N],v[N];
bool cmp(ND a,ND b)
{
    return a.x<b.x;
}
void ae(int f,int t)
{
    e[++cnt].to = t;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
int dep[N],fa[N],siz[N],son[N],tp[N];
void dfs1(int u,int f)
{
    siz[u]=1;
    for(int j=hed[u];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(to == f)continue;
        fa[to]=u;
        dep[to]=dep[u]+1;
        dfs1(to,u);
        siz[u]+=siz[to];
        if(siz[to]>siz[son[u]])son[u]=to;
    }
}
void dfs2(int u,int t)
{
    tp[u]=t;
    if(!son[u])return ;
    dfs2(son[u],t);
    for(int j=hed[u];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(to==fa[u]||to==son[u])continue;
        dfs2(to,to);
    }
}
int get_lca(int a,int b)
{
    while(tp[a]!=tp[b])
    {
        if(dep[tp[a]]<dep[tp[b]])swap(a,b);
        a=fa[tp[a]];
    }
    return dep[a]<dep[b]?a:b;
}
int tot,rt[N];
struct segtree
{
    int ls,rs;
    int vl;
}tr[80*N];
void update(int u)
{
    tr[u].vl=tr[tr[u].ls].vl+tr[tr[u].rs].vl;
}
void insert(int l,int r,int &u,int k,int qx)
{
    u = ++tot;
    tr[u].ls =tr[k].ls,tr[u].rs=tr[k].rs,tr[u].vl=tr[k].vl;
    if(l==r)
    {
        tr[u].vl++;
        return ;
    }
    int mid = (l+r)>>1;
    if(qx<=mid)insert(l,mid,tr[u].ls,tr[k].ls,qx);
    else insert(mid+1,r,tr[u].rs,tr[k].rs,qx);
    update(u);
}
void build(int u)
{
    insert(1,mx,rt[u],rt[fa[u]],v[u]);
    for(int j=hed[u];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(to==fa[u])continue;
        build(to);
    }
}
int query(int l,int r,int u,int v,int lca,int fl,int ned)
{
    if(l==r)return to[l];
    int k = tr[tr[u].ls].vl+tr[tr[v].ls].vl-tr[tr[lca].ls].vl-tr[tr[fl].ls].vl;
    int mid =  (l+r)>>1;
    if(ned<=k)return query(l,mid,tr[u].ls,tr[v].ls,tr[lca].ls,tr[fl].ls,ned);
    else return query(mid+1,r,tr[u].rs,tr[v].rs,tr[lca].rs,tr[fl].rs,ned-k);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&nd[i].x),nd[i].id=i;
    sort(nd+1,nd+1+n,cmp);
    int las = -1;
    for(int i=1;i<=n;i++)
    {
        if(nd[i].x!=las)
        {
            las=nd[i].x;
            to[++mx]=nd[i].x;
        }
        v[nd[i].id]=mx;
    }
    for(int f,t,i=1;i<n;i++)
    {
        scanf("%d%d",&f,&t);
        ae(f,t),ae(t,f);
    }
    dfs1(1,0),dfs2(1,1);
    build(1);
    int ans = 0;
    for(int u,v,k,i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&k);
        u^=ans;
        int lca = get_lca(u,v);
        ans =  query(1,mx,rt[u],rt[v],rt[lca],rt[fa[lca]],k);
        printf("%d\n",ans);
    }
    return 0;
}

 

bzoj2588 counting on a tree

标签:tin   query   insert   lca   color   def   cst   pre   ==   

原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9582007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!