您的位置:首页 > 其它

【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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCA 主席树 bzoj