# 【BZOJ-2588】Count on a tree 主席树 + 倍增

## 2588: Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 3749  Solved: 873
[Submit][Status][Discuss]

M行，表示每个询问的答案。

## Sample Input

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

2
8
9
105
7

HINT：
N,M<=100000

## Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define maxn 100010
int n,m;int val[maxn];int ls[maxn],num;
struct data{int to,next;}edge[maxn<<1];
int steck[maxn],top,father[maxn][25],deep[maxn],pos[maxn];
void dfs(int x)
{
steck[++top]=x; pos[x]=top;
for (int i=1; i<=20; i++)
if (deep[x]>=(1<<i))
father[x][i]=father[father[x][i-1]][i-1];
else break;
if (father[x][0]!=edge[i].to)
father[edge[i].to][0]=x,deep[edge[i].to]=deep[x]+1,dfs(edge[i].to);
}
int LCA(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
int dd=deep[x]-deep[y];
for (int i=0; i<=20; i++)
if (dd&(1<<i)) x=father[x][i];
for (int i=20; i>=0; i--)
if (father[x][i]!=father[y][i])
x=father[x][i],y=father[y][i];
if (x==y) return x; else return father[x][0];
}
int sum[maxn*20],ll[maxn*20],rr[maxn*20],root[maxn<<2],sz;
void update(int l,int r,int &now,int fat,int va)
{
now=++sz; sum[now]=sum[fat]+1;
if (l==r) return;
ll[now]=ll[fat],rr[now]=rr[fat];
int mid=(l+r)>>1;
if (va<=mid) update(l,mid,ll[now],ll[fat],va);
else update(mid+1,r,rr[now],rr[fat],va);
}
int query(int l,int r,int L,int R,int k)
{
int lca=LCA(L,R),fa=father[lca][0];
int a=root[pos[L]],b=root[pos[R]],c=root[pos[lca]],d=root[pos[fa]];
while (l<r)
{
int mid=(l+r)>>1;
int summ=sum[ll[a]]+sum[ll[b]]-sum[ll[c]]-sum[ll[d]];
if (summ>=k) r=mid,a=ll[a],b=ll[b],c=ll[c],d=ll[d];
else k-=summ,l=mid+1,a=rr[a],b=rr[b],c=rr[c],d=rr[d];
}
return l;
}
int main()
{
for (int i=1; i<=n; i++) val[i]=read(),ls[i]=val[i];
sort(ls+1,ls+n+1);
for (int i=1; i<=n; i++) if (ls[i]!=ls[i-1]) ls[++num]=ls[i];
for (int i=1; i<=n; i++) val[i]=lower_bound(ls+1,ls+num+1,val[i])-ls;
for (int u,v,i=1; i<=n-1; i++)
dfs(1);
for (int tmp,i=1; i<=n; i++)
tmp=steck[i],update(1,num,root[i],root[pos[father[tmp][0]]],val[tmp]);
int lastans=0,ans=0;
for (int u,v,k,i=1; i<=m; i++)
{
}