bzoj3631

来源:互联网 发布:2016安全事故数据统计 编辑:程序博客网 时间:2024/05/21 08:39

树剖 + 数组差分(就不用线段树)

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;inline int read(void){    int x = 0, c, f = 1;    do{c=getchar();if(c=='-')f=-1;}while(c<'0'||c>'9');    do{x=x*10+c-'0';c=getchar();}while(c>='0'&&c<='9');    return x * f;}#define root 1,n,1#define lson L,mid,o<<1#define rson mid+1,R,o<<1|1const int N = 301000;int to[2*N],nxt[2*N],fir[N],fa[N],Top[N],son[N],dep[N],siz[N],bel[N],col_cnt;int n, m, Index, go[N], delt[N];inline void addedge(int u,int v){    to[++Index] = v, nxt[Index] = fir[u], fir[u] = Index;}void dfs1(int x) {    dep[x] = dep[fa[x]] + 1;    siz[x] = 1;    for (int i = fir[x]; i; i = nxt[i]) if (to[i] != fa[x]) {        fa[to[i]] = x;        dfs1(to[i]);        son[x] = siz[son[x]] < siz[to[i]] ? to[i] : son[x];        siz[x] += siz[to[i]];    }}void dfs2(int x) {    Top[x] = son[fa[x]] == x ? Top[fa[x]] : x;    bel[x] = ++col_cnt;    if (son[x]) dfs2(son[x]);    for (int i = fir[x]; i; i = nxt[i]) if (to[i] != fa[x] && to[i] != son[x]){        dfs2(to[i]);    } }inline void up(int l,int r){    delt[l]++, delt[r+1]--;}inline void Updata(int u,int v) {    while (Top[u] != Top[v]) {        if (dep[Top[u]] < dep[Top[v]]) swap(u, v);        up(bel[Top[u]], bel[u]);        u = fa[Top[u]];    }    if (dep[u] < dep[v]) swap(u, v);     up(bel[v], bel[u]);}int main() {    int n = read();    for (int i = 1; i <= n; i++) {        go[i] = read();    }    for (int i = 1, u, v; i < n; i++) {        u = read(), v = read();        addedge(u,v), addedge(v,u);    } dfs1(1), dfs2(1);    for (int i = 1; i < n; i++)        Updata(go[i], go[i + 1]);    for (int i = 2; i <= n; i++) {        delt[i] += delt[i - 1];    }    for (int i = 2; i <= n; i++) {        delt[bel[go[i]]]--;    }    for (int i = 1; i <= n; i++) {        printf("%d\n",delt[bel[i]]);    }}
原创粉丝点击