LCA/RMQ预处理

来源:互联网 发布:眼镜厂景品手办淘宝店 编辑:程序博客网 时间:2024/05/17 04:12

以HDU 3078 为例。通过LCA/RMQ,找到u,v之间的第K大值即可。

#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <map>using namespace std;const int maxn = 80010;int weight[maxn];int n, Q;vector <int> Tree[maxn];bool vis[maxn];int fa[maxn];int d[maxn*2][20];int top;int dfn[maxn*2], euler[maxn*2], pos[maxn];void init(){top = 0;}void dfs(int u){vis[u] = 1;for(int i = 0; i < Tree[u].size(); i++){int v = Tree[u][i];if(vis[v]) continue;fa[v] = u;dfs(v);}}void DFS(int u, int dep){vis[u] = 1;dfn[top] = dep;euler[top] = u;pos[u] = top;++top;for(int i = 0; i < Tree[u].size(); i++){int v = Tree[u][i];if(vis[v]) continue;DFS(v, dep+1);dfn[top] = dep;euler[top] = u;++top;}}void RMQ_init(int n){for(int i = 1; i <= n; i++) d[i][0] = i;for(int j = 1; (1<<j) <= n; j++)for(int i = 1; i + (1<<j)-1 <= n; i++){if(dfn[d[i][j-1]] < dfn[d[i + (1<<(j-1))][j-1]]) d[i][j] = d[i][j-1];else d[i][j] = d[i + (1<<(j-1))][j-1];}}int RMQ(int L, int R){int k = 0;while(1<<(k+1) <= R-L+1) k++;if(dfn[d[L][k]] < dfn[d[R-(1<<k)+1][k]]) return d[L][k];return d[R-(1<<k)+1][k];}int LCA(int u, int v){if(pos[u] > pos[v])  swap(u, v);return euler[RMQ(pos[u], pos[v])];}void read_case(){top = 0;scanf("%d%d", &n, &Q);for(int i = 1; i <= n; i++) scanf("%d", &weight[i]);for(int i = 1; i < n; i++){int u, v;scanf("%d%d", &u, &v);Tree[u].push_back(v);Tree[v].push_back(u);}}vector<int> res;int cmp(int a, int b) { return a > b; }int cal(int u, int v, int k, int lca){res.clear();res.push_back(weight[u]);while(u != lca){u = fa[u];res.push_back(weight[u]);}if(v != lca) res.push_back(weight[v]);while(v != lca){v = fa[v];if(v == lca) break;res.push_back(weight[v]);}if(res.size() < k) return -1;sort(res.begin(), res.end(), cmp);return res[k-1];}void solve(){read_case();fa[1] = 1;DFS(1, 0);RMQ_init(top);memset(vis, 0, sizeof(vis));dfs(1);while(Q--){int k, u, v;scanf("%d%d%d", &k, &u, &v);if(k != 0){int lca = LCA(u, v);int ans;if((ans = cal(u, v, k, lca)) < 0) printf("invalid request!\n");else printf("%d\n", ans);}else weight[u] = v;}}int main(){solve();system("pause");return 0;}


 

原创粉丝点击