您的位置:首页 > 其它

bzoj2588 Spoj 10628. Count on a tree

2016-04-19 00:15 337 查看
主席树

#include<cstdio>
#include<algorithm>
#include<map>
#define N 2000010
using namespace std;
map<int,int>ma;
int n,m,i,a,b,c,e
,last,d
,id
,deep
,j;
int dp,pre
,p
,tt
,l
,r
,ls
,rs
,s
,tot,root
;
int jump[100100][19];
void link(int x,int y)
{
dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
}
void build(int &x,int a,int b)
{
tot++;x=tot;
l[x]=a;r[x]=b;
if (b-a>1)
{
int m=(a+b)>>1;
build(ls[x],a,m);
build(rs[x],m,b);
}
}
void insert(int &x,int y,int a,int b)
{
tot++;x=tot;
l[x]=l[y];r[x]=r[y];
ls[x]=ls[y];rs[x]=rs[y];s[x]=s[y];
if ((a<=l[x])&&(r[x]<=b))
{
s[x]++;
return;
}
int m=(l[x]+r[x])>>1;
if (a<m) insert(ls[x],ls[y],a,b);
if (m<b) insert(rs[x],rs[y],a,b);
s[x]=s[ls[x]]+s[rs[x]];
}
void dfs(int x,int fa)
{
int i=p[x];
insert(root[x],root[fa],e[x]-1,e[x]);
jump[x][0]=fa;
deep[x]=deep[fa]+1;
while (i)
{
if (tt[i]!=fa) dfs(tt[i],x);
i=pre[i];
}
}
int query(int x,int y,int z,int w,int c)
{
if (r[x]-l[x]==1)
{
return r[x];
}
int tmp=s[ls[x]]+s[ls[y]]-2*s[ls[z]];
if ((l[ls[x]]<w)&&(w<=r[ls[x]])) tmp++;
if (tmp>=c)
return query(ls[x],ls[y],ls[z],w,c);
else
return query(rs[x],rs[y],rs[z],w,c-tmp);
}
int lca(int a,int b)
{
int i;
if (deep[a]<deep[b]) a^=b^=a^=b;
for (i=17;i>=0;i--)
if (deep[jump[a][i]]>=deep[b]) a=jump[a][i];
if (a==b) return a;

for (i=17;i>=0;i--)
if (jump[a][i]!=jump[b][i])
{
a=jump[a][i];
b=jump[b][i];
}
return jump[a][0];
}
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%d",&e[i]);
d[i]=e[i];
}
sort(d+1,d+1+n);int cnt=0;d[0]=-0x37373737;
for (i=1;i<=n;i++)
{
if (d[i]!=d[i-1]) cnt++;
ma[d[i]]=cnt;
id[cnt]=d[i];
}
for (i=1;i<=n;i++) e[i]=ma[e[i]];
for (i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
link(a,b);
link(b,a);
}
build(root[0],0,cnt);
dfs(1,0);

for (i=1;i<=17;i++)
for (j=1;j<=n;j++)
jump[j][i]=jump[jump[j][i-1]][i-1];

int ans=0;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
a^=ans;
int LCA=lca(a,b);
//printf("%d %d %d\n",s[root[a]],s[root[b]],LCA);
ans=id[query(root[a],root[b],root[LCA],e[LCA],c)];
printf("%d",ans);
if (i!=m) printf("\n");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: