求助
查看原帖
求助
437398
EastIsRed楼主2022/9/25 15:31
#include<stdio.h>
#include<string.h>
#include<map>
using namespace std;
int n,m;
int a[100086];

//链式前向星
int head[100086],nxt[100086],to[100086],edge_tot;
void add_edge(int u,int v);

//主席树
struct node{
    int l,r,val;
}tr[40000086];
int root[100086],seg_tot;
int b[100086];
map<int,int>mp;
void build(int& now,int l,int r);
void insert(int &now,int pnow,int l,int r,int pos);
int get(int t1,int t2,int t3,int t4,int l,int r,int rk);

//树剖
int fa[100086],hevs[100086],dep[100086],siz[100086];
int dfn[100086],rfn[100086],top[100086],tcp_tot;
void dfs1(int now,int f);
void dfs2(int now);
int lca(int u,int v);

inline void init();
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",a+i);
    memset(head,0xff,sizeof(head));
    memset(nxt,0xff,sizeof(nxt));
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add_edge(u,v);
    }
    init();
    int last=0;
    while(m--)
    {
        int u,v,k;
        scanf("%d%d%d",&u,&v,&k);
        u^=last;
        int temp=lca(u,v);
        printf("%d\n",last=get(root[u],root[v],root[temp],root[fa[temp]],1,mp.size(),k));
    }
    return 0;
}

//函数实现
void add_edge(int u,int v)
{
    to[edge_tot]=v;
    nxt[edge_tot]=head[u];
    head[u]=edge_tot++;
}
void build(int& now,int l,int r)
{
    if(!now)
        now=++seg_tot;
    if(l!=r)
    {
        int mid=l+r>>1;
        build(tr[now].l,l,mid);
        build(tr[now].r,mid+1,r);
    }
}
void insert(int &now,int pnow,int l,int r,int pos)
{
    if(!now)
        now=++seg_tot;
    tr[now].val=tr[pnow].val+1;
    if(l>=r)
        return;
    int mid=l+r>>1;
    if(pos<=mid)
    {
        tr[now].r=tr[pnow].r;
        insert(tr[now].l,tr[pnow].l,l,mid,pos);
    }
    else
    {
        tr[now].l=tr[pnow].l;
        insert(tr[now].r,tr[pnow].r,mid+1,r,pos);
    }
}
int get(int t1,int t2,int t3,int t4,int l,int r,int rk)
{
    if(l==r)
        return b[l];
    int lrk=tr[tr[t1].l].val+tr[tr[t2].l].val-tr[tr[t3].l].val-tr[tr[t4].l].val;
    int mid=l+r>>1;
    if(lrk>=rk)
        return get(tr[t1].l,tr[t1].l,tr[t3].l,tr[t4].l,l,mid,rk);
    return get(tr[t1].r,tr[t1].r,tr[t3].r,tr[t4].r,mid+1,r,rk-lrk);
}
void dfs1(int now,int f)
{
    insert(root[now],root[f],1,mp.size(),mp[a[now]]);
    fa[now]=f;
    dep[now]=dep[f]+1;
    siz[now]=1;
    for(int i=head[now];~i;i=nxt[i])
    {
        dfs1(to[i],now);
        if(siz[hevs[now]]<siz[to[i]])
            hevs[now]=to[i];
    }
}
void dfs2(int now)
{
    dfn[now]=++tcp_tot;
    rfn[tcp_tot]=now;
    if(hevs[now])
    {
        top[hevs[now]]=top[now];
        dfs2(hevs[now]);
    }
    for(int i=head[now];~i;i=nxt[i])
        if(!top[to[i]])
        {
            top[to[i]]=to[i];
            dfs2(to[i]);
        }
}
int lca(int u,int v)
{
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])
            u^=v,v^=u,u^=v;
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])
        u^=v,v^=u,u^=v;
    return u;
}
inline void init()
{
    for(int i=1;i<=n;i++)
        mp[a[i]]=1;
    int temp=1;
    for(map<int,int>::iterator iter=mp.begin();iter!=mp.end();iter++)
    {
        b[temp]=iter->first;
        iter->second=temp;
        temp++;
    }
    build(root[0],1,mp.size());
    dfs1(1,0);
    top[1]=1;
    dfs2(1);
}

样例都没过,大佬帮忙看看

2022/9/25 15:31
加载中...