洛谷P2633 Count on a tree 主席树

传送门:主席树

解题报告:

传送门!

就非常板子昂$QwQ$

直接dfs,在dfs的过程中建树

然后就直接查询就好

其实我jio得就是个主席树板子题套在树上,,,?

然后具体处理也不难想?就考虑树上差分,形式大概就是tr[r]+tr[l]-tr[lca]-tr[lca.fa]

然后其他做法就都和主席树的板子一样辣辣辣!

快乐地发现有个双倍经验嘻嘻

洛谷P2633 Count on a tree 主席树洛谷P2633 Count on a tree 主席树
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define fr first
#define sc second
#define rg register
#define gc getchar()
#define mp make_pair
#define t(i) edge[i].to
#define rp(i,x,y) for(rg int i=x;i<=y;++i)
#define my(i,x,y) for(rg int i=x;i>=y;--i)
#define e(i,x) for(rg int i=head[x];i;i=edge[i].nxt)

const int N=100000+10;
int n,m,a[N],st[N],rt[N],cnt,n_lsh,head[N],ed_cnt,as,fa[N][20],dep[N],poww[25]={1};
struct node{int ls,rs,l,r,val;}tr[N*30];
struct ed{int to,nxt;}edge[N<<1];

il int read()
{
    rg char ch=gc;rg int x=0;rg bool y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il void ad(int x,int y){edge[++ed_cnt]=(ed){x,head[y]};head[y]=ed_cnt;}
il void build(int x,int l,int r)
{
    ++cnt;tr[x].l=l,tr[x].r=r;if(l==r)return;
    int mid=(l+r)>>1;tr[x].ls=cnt+1;build(tr[x].ls,l,mid);tr[x].rs=cnt+1;build(tr[x].rs,mid+1,r);return;
}
il void updat(int x,int dat)
{
    ++cnt;tr[cnt]=tr[x];++tr[cnt].val;if(tr[cnt].l==tr[cnt].r)return;
    int mid=(tr[cnt].l+tr[cnt].r)>>1;
    if(dat<=mid){tr[cnt].ls=cnt+1;updat(tr[x].ls,dat);}else{tr[cnt].rs=cnt+1;updat(tr[x].rs,dat);}
}
il int query(int x,int xx,int x1,int x2,int dat)
{
    if(tr[x1].l==tr[x1].r)return tr[x1].l;int ret=tr[tr[x2].ls].val+tr[tr[x1].ls].val-tr[tr[x].ls].val-tr[tr[xx].ls].val;
    if(ret<dat)return query(tr[x].rs,tr[xx].rs,tr[x1].rs,tr[x2].rs,dat-ret);return query(tr[x].ls,tr[xx].ls,tr[x1].ls,tr[x2].ls,dat);
}
il void dfs(int x,int fat){fa[x][0]=fat;dep[x]=dep[fat]+1;rp(i,1,19)fa[x][i]=fa[fa[x][i-1]][i-1];e(i,x)if(t(i)^fat)rt[t(i)]=cnt+1,updat(rt[x],a[t(i)]),dfs(t(i),x);}
il int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    my(i,19,0)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];if(x==y)return x;
    my(i,19,0)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}

int main()
{
    n=read();m=read();rp(i,1,n)a[i]=st[i]=read();sort(st+1,st+1+n);n_lsh=unique(st+1,st+1+n)-st-1;rp(i,1,n)a[i]=lower_bound(st+1,st+n_lsh+1,a[i])-st;
    rt[0]=1;build(1,1,n_lsh);rt[1]=cnt+1;updat(1,a[1]);
    rp(i,1,n-1){int x=read(),y=read();ad(x,y);ad(y,x);}dfs(1,0);
    rp(i,1,20)poww[i]=poww[i-1]<<1;
    rp(i,1,m){int l=read()^as,r=read(),x=read(),lcaa=lca(l,r);printf("%d\n",as=st[query(rt[fa[lcaa][0]],rt[lcaa],rt[l],rt[r],x)]);}
    return 0;
}
放下代码就好辣!