bzoj3631

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

#include
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|1
const 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]]);
    }
}

你可能感兴趣的:(bzoj,数据结构)