【BZOJ 2588】Count on a tree 【树上路径第K大】【LCA+主席树】
2016-10-19 08:39
471 查看
其实不难..只是bug不好调QAQ
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#define g() getchar()
#define d(x) isdigit(x)
#define pb(x) push_back(x)
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rep0(i,s,t) for(int i=(s);i>=(t);i--)
#define repe(i,s) for(int i=head[s];~i;i=e[i].next)
#define maxn 100010
using namespace std;
char ch;int last,n,m;
inline void F(int& x){
for(x=0,ch=g();!d(ch);ch=g());
for(;d(ch);x=x*10+ch-'0',ch=g());
}
int w[maxn],head[maxn],eid=1,tot;vector<int> hs;
struct Edge{
int to,next;
}e[maxn<<1];
inline void adde(int u,int v){
e[eid].to=v;
e[eid].next=head[u];
head[u]=eid++;
}
inline int getrank(int x){return lower_bound(hs.begin(),hs.end(),x)-hs.begin()+1;}
int deep[maxn],fa[maxn][20],idx,dfn[maxn],pos[maxn];
void dfs(int u){
++idx;dfn[idx]=u;pos[u]=idx;
rep(i,1,17){
if((1<<i)<=deep[u])fa[u][i]=fa[fa[u][i-1]][i-1];
else break;
}
repe(i,u){
int& v = e[i].to;
if(fa[u][0]!=v){
deep[v] = deep[u]+1;
fa[v][0] = u;
dfs(v);
}
}
}
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
rep0(i,17,0)if(deep[y]+(1<<i)<=deep[x])x=fa[x][i];
if(x==y)return x;
rep0(i,17,0)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int root[maxn],cnt;
struct Node{
int ls,rs,sum;
}tr[maxn*40];
void update(int& u,int v,int l,int r,int p)
{
++cnt;u=cnt;tr[u]=tr[v];tr[u].sum++;
if(l==r)return;
int mid = (l+r)>>1;
if(p<=mid)update(tr[u].ls,tr[v].ls,l,mid,p);
else update(tr[u].rs,tr[v].rs,mid+1,r,p);
}
int query(int x,int y,int k)
{
int c=lca(x,y);int d = root[pos[fa[c][0]]];c=root[pos[c]];
int a=root[pos[x]],b=root[pos[y]];
int l=1,r=tot,mid,delt;
while(l<r)
{
mid=(l+r)>>1;
delt = tr[tr[a].ls].sum+tr[tr[b].ls].sum-tr[tr[c].ls].sum-tr[tr[d].ls].sum;
if(delt>=k){
r = mid;a=tr[a].ls;b=tr[b].ls;c=tr[c].ls;d=tr[d].ls;
}else{
l = mid+1;a=tr[a].rs;b=tr[b].rs;c=tr[c].rs;d=tr[d].rs;
k-=delt;
}
}
return hs[l-1];
}
int main()
{
memset(head,-1,sizeof(head));
F(n),F(m);int a,b,k,t;
rep(i,1,n)F(w[i]),hs.pb(w[i]);
sort(hs.begin(),hs.end());
hs.erase(unique(hs.begin(),hs.end()),hs.end());
tot = hs.size();
rep(i,1,n)w[i]=getrank(w[i]);
rep(i,1,n-1){F(a),F(b); adde(a,b);adde(b,a);}
dfs(1);
rep(i,1,n){int& tp = dfn[i];update(root[i],root[pos[fa[tp][0]]],1,tot,w[tp]);}
t = 0;
rep(i,1,m){
F(a),F(b),F(k);
a^=t;
t = query(a,b,k);
printf("%d",t);
if(i!=m)puts("");
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#define g() getchar()
#define d(x) isdigit(x)
#define pb(x) push_back(x)
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rep0(i,s,t) for(int i=(s);i>=(t);i--)
#define repe(i,s) for(int i=head[s];~i;i=e[i].next)
#define maxn 100010
using namespace std;
char ch;int last,n,m;
inline void F(int& x){
for(x=0,ch=g();!d(ch);ch=g());
for(;d(ch);x=x*10+ch-'0',ch=g());
}
int w[maxn],head[maxn],eid=1,tot;vector<int> hs;
struct Edge{
int to,next;
}e[maxn<<1];
inline void adde(int u,int v){
e[eid].to=v;
e[eid].next=head[u];
head[u]=eid++;
}
inline int getrank(int x){return lower_bound(hs.begin(),hs.end(),x)-hs.begin()+1;}
int deep[maxn],fa[maxn][20],idx,dfn[maxn],pos[maxn];
void dfs(int u){
++idx;dfn[idx]=u;pos[u]=idx;
rep(i,1,17){
if((1<<i)<=deep[u])fa[u][i]=fa[fa[u][i-1]][i-1];
else break;
}
repe(i,u){
int& v = e[i].to;
if(fa[u][0]!=v){
deep[v] = deep[u]+1;
fa[v][0] = u;
dfs(v);
}
}
}
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
rep0(i,17,0)if(deep[y]+(1<<i)<=deep[x])x=fa[x][i];
if(x==y)return x;
rep0(i,17,0)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int root[maxn],cnt;
struct Node{
int ls,rs,sum;
}tr[maxn*40];
void update(int& u,int v,int l,int r,int p)
{
++cnt;u=cnt;tr[u]=tr[v];tr[u].sum++;
if(l==r)return;
int mid = (l+r)>>1;
if(p<=mid)update(tr[u].ls,tr[v].ls,l,mid,p);
else update(tr[u].rs,tr[v].rs,mid+1,r,p);
}
int query(int x,int y,int k)
{
int c=lca(x,y);int d = root[pos[fa[c][0]]];c=root[pos[c]];
int a=root[pos[x]],b=root[pos[y]];
int l=1,r=tot,mid,delt;
while(l<r)
{
mid=(l+r)>>1;
delt = tr[tr[a].ls].sum+tr[tr[b].ls].sum-tr[tr[c].ls].sum-tr[tr[d].ls].sum;
if(delt>=k){
r = mid;a=tr[a].ls;b=tr[b].ls;c=tr[c].ls;d=tr[d].ls;
}else{
l = mid+1;a=tr[a].rs;b=tr[b].rs;c=tr[c].rs;d=tr[d].rs;
k-=delt;
}
}
return hs[l-1];
}
int main()
{
memset(head,-1,sizeof(head));
F(n),F(m);int a,b,k,t;
rep(i,1,n)F(w[i]),hs.pb(w[i]);
sort(hs.begin(),hs.end());
hs.erase(unique(hs.begin(),hs.end()),hs.end());
tot = hs.size();
rep(i,1,n)w[i]=getrank(w[i]);
rep(i,1,n-1){F(a),F(b); adde(a,b);adde(b,a);}
dfs(1);
rep(i,1,n){int& tp = dfn[i];update(root[i],root[pos[fa[tp][0]]],1,tot,w[tp]);}
t = 0;
rep(i,1,m){
F(a),F(b),F(k);
a^=t;
t = query(a,b,k);
printf("%d",t);
if(i!=m)puts("");
}
return 0;
}
相关文章推荐
- bzoj2588 Count on a tree(树上建主席树求路径第k大)
- bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)
- 2588: Spoj 10628. Count on a tree (主席树,树上路径第K大值)
- BZOJ.2588.Count on a tree(主席树 静态树上第k小)
- bzoj 2588: Spoj 10628. Count on a tree(树上主席树)
- BZOJ 2588 Count On a Tree 【LCA】【主席树】
- BZOJ 2588 Count on a tree(树上的主席树)
- 【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树
- BZOJ BZOJ 2588: Spoj 10628. Count on a tree 树上主席树
- SPOJ - COT Count on a tree 树上主席树+LCA+任意路径问题
- [BZOJ2588][Spoj10628]Count on a tree(树上主席树)
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
- BZOJ2588 Count on a tree <DFS序+LCA+值域主席树>
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
- 【BZOJ2588】Spoj 10628. Count on a tree【主席树】【LCA】
- [bzoj2588][count on a tree] (主席树+lca)
- 【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA
- BZOJ-2588-Count-on-a-tree-SPOJ10628-LCA+主席树
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
- 【bzoj2588】Spoj 10628. Count on a tree LCA+主席树