[BZOJ2588][SPOJ10628]Count on a tree
题目大意:
给定一棵$n(n\leq100000)$个结点的带点权的树,有$m(m\leq100000)$组询问,每次询问$u$到$v$的路径上第$k$小的权值。强制在线。
思路:
每个结点根据父结点建立可持久化权值线段树,查询时就查询$u+v-lca(u,v)-par[lca(u,v)]$的树即可。
1 #include<list> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=100001,M=100000,logN=17; 13 int w[N],tmp[N],dep[N],anc[N][logN]; 14 std::list<int> e[N]; 15 inline void add_edge(const int &u,const int &v) { 16 e[u].push_back(v); 17 e[v].push_back(u); 18 } 19 class FotileTree { 20 private: 21 struct Node { 22 int val; 23 Node *left,*right; 24 Node() {} 25 Node(const Node *const &p) { 26 *this=*p; 27 } 28 }; 29 public: 30 Node *root[N]; 31 FotileTree() { 32 root[0]=new Node; 33 root[0]->left=root[0]->right=root[0]; 34 } 35 Node *modify(const Node *const &last,const int &b,const int &e,const int &x) { 36 Node *const p=new Node(last); 37 p->val++; 38 if(b==e) return p; 39 const int mid=(b+e)>>1; 40 if(x<=mid) p->left=modify(last->left,b,mid,x); 41 if(x>mid) p->right=modify(last->right,mid+1,e,x); 42 return p; 43 } 44 int query(const Node *const &p1,const Node *const &p2,const Node *const &p3,const Node *const &p4,const int &b,const int &e,const int &k) { 45 if(b==e) return b; 46 const int mid=(b+e)>>1; 47 if(k<=p1->left->val+p2->left->val-p3->left->val-p4->left->val) return query(p1->left,p2->left,p3->left,p4->left,b,mid,k); 48 return query(p1->right,p2->right,p3->right,p4->right,mid+1,e,k-(p1->left->val+p2->left->val-p3->left->val-p4->left->val)); 49 } 50 }; 51 FotileTree t; 52 inline int log2(const float &x) { 53 return ((unsigned&)x>>23&255)-127; 54 } 55 void dfs(const int &x,const int &par) { 56 t.root[x]=t.modify(t.root[par],1,tmp[0],w[x]); 57 anc[x][0]=par; 58 dep[x]=dep[par]+1; 59 for(register int i=1;i<=log2(dep[x]);i++) { 60 anc[x][i]=anc[anc[x][i-1]][i-1]; 61 } 62 for(std::list<int>::iterator i=e[x].begin();i!=e[x].end();i++) { 63 const int &y=*i; 64 if(y==par) continue; 65 dfs(y,x); 66 } 67 } 68 inline int get_lca(int u,int v) { 69 if(dep[u]<dep[v]) std::swap(u,v); 70 while(dep[u]!=dep[v]) { 71 u=anc[u][log2(dep[u]-dep[v])]; 72 } 73 if(u==v) return u; 74 for(register int i=log2(dep[u]);~i;i--) { 75 if(anc[u][i]!=anc[v][i]) { 76 u=anc[u][i]; 77 v=anc[v][i]; 78 } 79 } 80 return anc[u][0]; 81 } 82 int main() { 83 const int n=getint(),m=getint(); 84 for(register int i=1;i<=n;i++) { 85 w[i]=tmp[i]=getint(); 86 } 87 std::sort(&tmp[1],&tmp[n]+1); 88 tmp[0]=std::unique(&tmp[1],&tmp[n]+1)-&tmp[1]; 89 for(register int i=1;i<=n;i++) { 90 w[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,w[i])-&tmp[0]; 91 } 92 for(register int i=1;i<n;i++) { 93 add_edge(getint(),getint()); 94 } 95 dfs(1,0); 96 for(register int i=0,ans=0;i<m;i++) { 97 const int u=getint()^ans,v=getint(),k=getint(),lca=get_lca(u,v); 98 if(i) putchar('\n'); 99 printf("%d",ans=tmp[t.query(t.root[u],t.root[v],t.root[lca],t.root[anc[lca][0]],1,tmp[0],k)]); 100 } 101 return 0; 102 }