2588: Spoj 10628. Count on a tree
Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3607 Solved: 840
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
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
Sample Output
8
9
105
7
HINT
暴力自重。。。
解题思路:复习一下树链剖分和主席树。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,len,sug,size_z,tail,ans;
int zhi[110000];
struct ss
{
int zhi,dui;
}qg[110000];
struct sg
{
int x,y;
}q[110000];
int to[210000],next[210000],h[110000],deep[110000],son[110000],size[110000],fa[110000];
int dui[210000],messi[210000],hash[210000],top[210000],root[110000];
int sum[2200000],l[2200000],r[2200000];
void insert(int x,int y){++len; to[len]=y; next[len]=h[x]; h[x]=len;}
inline int read()
{
char y;int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int (y)-48; y=getchar();}
return x*f;
}
bool cmp(ss x,ss y) {return x.zhi<y.zhi;}
void dfs1(int now,int f,int lg)
{
deep[now]=lg;
int u=h[now]; size[now]=1; son[now]=0; fa[now]=f;
while (u!=0)
{
if (to[u]!=f)
{
dfs1(to[u],now,lg+1);
size[now]+=size[to[u]];
if (size[to[u]]>size[son[now]]) son[now]=to[u];
}
u=next[u];
}
}
void dfs2(int now,int f,int tp)
{
++sug; dui[now]=sug; messi[sug]=zhi[now];
if (tp!=-1) top[now]=tp; else top[now]=now;
if (son[now]==0) return; dfs2(son[now],now,top[now]);
int u=h[now];
while (u!=0)
{
if (to[u]!=f && to[u]!=son[now])
{
dfs2(to[u],now,-1);
}
u=next[u];
}
}
void build(int x,int &y,int lg,int rg,int zhi)
{
++size_z; y=size_z; sum[size_z]=sum[x]+1;
if (lg==rg) return;
int mid=(lg+rg)/2;
if (zhi<=mid)
{
l[y]=l[x]; r[y]=r[x];
build(l[x],l[y],lg,mid,zhi);
}else
{
l[y]=l[x]; r[y]=r[x];
build(r[x],r[y],mid+1,rg,zhi);
}
}
int query(int lg,int rg,int k)
{
if (lg==rg) return lg;
int sa=0;
for (int i=1;i<=tail;++i)
{
sa=sa+sum[l[q[i].y]]-sum[l[q[i].x]];
}
int mid=(lg+rg)/2;
if (sa>=k)
{
for (int i=1;i<=tail;++i) {q[i].y=l[q[i].y]; q[i].x=l[q[i].x];}
return query(lg,mid,k);
}else
{
for (int i=1;i<=tail;++i) {q[i].y=r[q[i].y]; q[i].x=r[q[i].x];}
return query(mid+1,rg,k-sa);
}
}
int main()
{
n=read(); m=read();
for (int i=1;i<=n;++i)
{
qg[i].zhi=read(); qg[i].dui=i;
}
sort(qg+1,qg+n+1,cmp);
int op=0;
for (int i=1;i<=n;++i)
{
if (qg[i].zhi!=qg[i-1].zhi){op+=1;} hash[op]=qg[i].zhi;
zhi[qg[i].dui]=op;
}
for (int i=1;i<=n-1;++i)
{
int x=read(); int y=read(); insert(x,y); insert(y,x);
}
dfs1(1,0,1); sug=0;
dfs2(1,0,-1); size_z=0;
for (int i=1;i<=n;++i)
{
build(root[i-1],root[i],1,op,messi[i]);
}
ans=0;
for (int i=1;i<=m;++i)
{
int u,v,k; u=read(); v=read(); k=read();
u=ans^u;
tail=0;
while (top[u]!=top[v])
{
if (deep[top[u]]>=deep[top[v]])
{
++tail; q[tail].x=root[dui[top[u]]-1]; q[tail].y=root[dui[u]]; u=fa[top[u]];
}else
{
++tail; q[tail].x=root[dui[top[v]]-1]; q[tail].y=root[dui[v]]; v=fa[top[v]];
}
}
if (deep[u]>deep[v]) swap(u,v); ++tail; q[tail].x=root[dui[u]-1]; q[tail].y=root[dui[v]];
ans=hash[query(1,op,k)];
if (i<=m)printf("%d\n",ans);else printf("%d",ans);
}
}