LCA RMQ演算法模板
阿新 • • 發佈:2019-02-04
題目:HDU 3078 Network
主要貼一下LCA RMQ的演算法模板,供以後回憶
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <vector> #include <set> #include <map> #include <queue> using namespace std; const int maxn = 80005; int n,q,dfs_clock; int val[maxn],id[maxn],vs[maxn*2],depth[maxn *2],dp[maxn*2][30],pre[maxn],temp[maxn]; vector <int> g[maxn]; void dfs(int u,int fa,int d) { id[u]=dfs_clock; vs[dfs_clock]=u; depth[dfs_clock++]=d; int len = g[u].size(); for(int i=0;i<len;i++) { int v = g[u][i]; if(v==fa) continue; pre[v]=u; dfs(v,u,d+1); vs[dfs_clock]=u; depth[dfs_clock++]=d; } } void find_depth() { dfs_clock=1; memset(id,0,sizeof(id)); memset(vs,0,sizeof(vs)); memset(depth,0,sizeof(depth)); dfs(1,-1,0); } void RMQ_init(int n) { for(int i=1;i<=n;i++) { dp[i][0]=i; } for(int j=1;(1<<j)<=n;j++) { for(int i=1;i+(1<<j)-1<=n;i++) { int a = dp[i][j-1]; int b = dp[i+(1<<(j-1))][j-1]; dp[i][j] = depth[a] <= depth[b] ? a:b; } } } int query(int L,int R) { int k=0; while((1<<(k+1))<=R-L+1) k++; int a = dp[L][k]; int b = dp[R-(1<<k)+1][k]; return depth[a]<=depth[b] ? a:b; } int LCA(int u,int v) { int x = id[u]; int y = id[v]; return x<y? vs[query(x,y)]:vs[query(y,x)]; } int main() { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) { scanf("%d",&val[i]); } for(int i=0;i<=n;i++) { g[i].clear(); } for(int i=0;i<n-1;i++) { int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } find_depth(); RMQ_init(dfs_clock-1); for(int i=0;i<q;i++) { int k,a,b; scanf("%d%d%d",&k,&a,&b); if(!k) { val[a]=b; } else { int anc = LCA(a,b),cnt=0; int cur = a; while(cur!=anc) { temp[cnt++]=val[cur]; cur = pre[cur]; } cur = b; while(cur!=anc) { temp[cnt++]=val[cur]; cur = pre[cur]; } temp[cnt++] = val[anc]; if(cnt < k) { printf("invalid request!\n"); } else { sort(temp,temp+cnt,greater<int> ()); printf("%d\n",temp[k-1]); } } } system("pause"); return 0; }