差不多可以说是树链剖分的模板题了,直接维护即可。

#include <bits/stdc++.h>

using namespace std;

#define REP(i,n)                for(int i(0); i <  (n); ++i)
#define rep(i,a,b) for(int i(a); i <= (b); ++i)
#define dec(i,a,b) for(int i(a); i >= (b); --i)
#define for_edge(i,x) for(int i = H[x]; i; i = X[i]) #define LL long long
#define ULL unsigned long long
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
#define INF 1 << 30 const int N = 300000 + 10;
const int M = 10000 + 10;
const int Q = 1000 + 10;
const int A = 30 + 1; int E[N << 1], H[N << 1], X[N << 1];
int c[N];
int top[N];
int fa[N];
int deep[N];
int num[N];
int son[N];
int fp[N];
int p[N];
int et, pos;
int a[N];
int n, x, y; inline int lowbit(int x){ return (x) & (-x);} inline int query(int x){int ret = 0; for (; x; x -= lowbit(x)) ret += c[x]; return ret;}
inline void add(int x, int val){ for (; x <= n; x += lowbit(x)) c[x] += val;} inline void addedge(int a, int b){
E[++et] = b, X[et] = H[a], H[a] = et;
E[++et] = a, X[et] = H[b], H[b] = et;
} void dfs(int x, int pre){
deep[x] = deep[pre] + 1;
fa[x] = pre;
num[x] = 1;
for_edge(i, x){
int v = E[i];
if (v != pre){
dfs(v, x);
num[x] += num[v];
if (son[x] != -1 || num[v] > num[son[x]])
son[x] = v;
}
}
} void getpos(int x, int sp){
top[x] = sp;
p[x] = ++pos;
fp[p[x]] = x;
if (son[x] == -1) return;
getpos(son[x], sp);
for_edge(i, x){
int v = E[i];
if (v != son[x] && v != fa[x])
getpos(v, v);
}
} void cover(int u, int v, int val){
int f1 = top[u], f2 = top[v];
int tmp = 0;
while (f1 != f2){
if (deep[f1] < deep[f2]){
swap(f1, f2);
swap(u, v);
}
add(p[f1], val);
add(p[u] + 1, -val);
u = fa[f1];
f1 = top[u];
} if (deep[u] > deep[v]) swap(u, v);
add(p[u], val);
add(p[v] + 1, -val);
} int main(){
#ifndef ONLINE_JUDGE
freopen("test.txt", "r", stdin);
freopen("test.out", "w", stdout);
#endif scanf("%d", &n);
rep(i, 1, n) scanf("%d", a + i);
rep(i, 1, n - 1){
scanf("%d%d", &x, &y);
addedge(x, y);
} memset(son, -1, sizeof son);
dfs(1, 0);
getpos(1, 1);
rep(i, 1, n - 1){
x = a[i], y = a[i + 1];
cover(x, y, 1);
} rep(i, 1, n) if (i == a[1]) printf("%d\n", query(p[i]));
else printf("%d\n", query(p[i]) - 1); return 0; }

最新文章

  1. android标题栏上面弹出提示框(二) PopupWindow实现,带动画效果
  2. R语言 recommenderlab 包
  3. centos7下安装vsftpd与PAM虚拟用户
  4. 【温故而知新-Javascript】比较 undefined 和 null 值
  5. 去掉linux 系统vi中出现^M字符的方法
  6. Bug 是改不完滴
  7. http状态代码含义表
  8. puppet运维配置实列
  9. css 多栏自适应布局
  10. PHPCMS标签大全
  11. 强制关闭myeclipse出现的问题
  12. PHP闭包Closure与array_reduce结合的一个范例
  13. 教你如何在Drcom下使用路由器上校园网(以广东工业大学、极路由1S HC5661A为例)
  14. Java实现堆排序和计数排序
  15. Python Pandas 简单使用之 API熟悉
  16. js數組
  17. CLOS网络架构与FATTREE胖树拓扑
  18. 机器学习:K-Means/K-Means++
  19. JVM优化-JVM参数配置
  20. Linux NTP服务配置 for Oracle RAC

热门文章

  1. Codeforces Round #459 (Div. 2):D. MADMAX(记忆化搜索+博弈论)
  2. DFS:Prime Ring Problem(素数环)
  3. mysql-不恰当的update语句使用主键和索引导致mysql死锁
  4. excel VBA 将文本数值转换为数字格式(单元格中数据左上角是绿三角,鼠标点上有叹号标示)
  5. jni 调用
  6. Robotium之Android控件定位实践和建议
  7. Python-S9——Day100-Web前端框架之Vue
  8. python-os模块及md5加密
  9. Leetcode 529.扫雷游戏
  10. Leetcode 523.连续的子数组和