bzoj3631

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/syh0313/article/details/88885484

树链剖分

晚上神志不清的时候写的,头晕眼花si初值忘记赋了,导致变成了随机连剖分(丢人.....)

/**************************************************************

    Problem: 3631

    User: syh0313

    Language: C++

    Result: Accepted

    Time:1828 ms

    Memory:61640 kb

****************************************************************/

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <cstring>

#include <string>

#define lch a[n].lc

#define rch a[n].rc

using namespace std;

const int maxn=400010;

int n,ord[maxn],topt,to[maxn<<1],st[maxn<<1],nt[maxn<<1],root,cnt;

int fa[maxn],rem[maxn],si[maxn],dep[maxn];

int dfn[maxn],line[maxn],dfn_num,top[maxn];

long long ans[maxn];

bool f[maxn];

struct da{int lc,rc;long long tag;}a[maxn<<2];

void add(int x,int y)

{to[++topt]=y; nt[topt]=st[x]; st[x]=topt;}

void dfs1(int x,int de)

{

    f[x]=1; dep[x]=de; si[x]=1; int p=st[x],ma=0;

    while (p)

    {

        if (!f[to[p]])

        {

            dfs1(to[p],de+1);

            fa[to[p]]=x; si[x]+=si[to[p]];

            if (si[to[p]]>ma) {ma=si[to[p]]; rem[x]=to[p];}

        }

        p=nt[p];

    }

}

void dfs2(int x)

{

    f[x]=1; if (rem[fa[x]]==x) top[x]=top[fa[x]];else top[x]=x;

    dfn[x]=++dfn_num; line[dfn_num]=x;

    if (rem[x]) dfs2(rem[x]);

    int p=st[x];

    while (p)

    {

        if (!f[to[p]]) dfs2(to[p]);

        p=nt[p];

    }

}

/*void build_tree(int &n,int l,int r)

{

    n=++cnt; if (l==r) return;

    int mid=(l+r)>>1;

    build_tree(lch,l,mid); build_tree(rch,mid+1,r);

}

*/

void tree_add(int &n,int L,int R,int l,int r)

{

    if (!n) n=++cnt;

    if (L==l && R==r) {a[n].tag++; return;}

    int mid=(L+R)>>1;

    if (r<=mid) tree_add(lch,L,mid,l,r);

    else if (l>=mid+1) tree_add(rch,mid+1,R,l,r);

    else tree_add(lch,L,mid,l,mid),tree_add(rch,mid+1,R,mid+1,r);

}

void tadd(int x,int y)

{

    while (top[x]!=top[y])

    {

        if (dep[top[x]]<dep[top[y]]) swap(x,y);

        tree_add(root,1,n,dfn[top[x]],dfn[x]);

        x=fa[top[x]];

    }

    if (dfn[x]>dfn[y]) swap(x,y);

    tree_add(root,1,n,dfn[x],dfn[y]);

}

void qury(int &n,int l,int r,long long k)

{

    if (!n) topt++;

    if (l==r) {ans[line[l]]=k; return;}

    int mid=(l+r)>>1;

    qury(lch,l,mid,k+a[lch].tag);

    qury(rch,mid+1,r,k+a[rch].tag);

}

int read()

{

    int xx=0,ff=1; char c=getchar();

    while (c<'0' || c>'9') {if (c=='-') ff=-1; c=getchar();}

    while (c>='0' && c<='9') {xx=(xx<<1)+(xx<<3)+c-'0'; c=getchar();}

return xx*ff;

}

int main()

{

    //freopen("1.in","r",stdin);

    n=read(); for (int i=1;i<=n;i++) ord[i]=read();

    for (int i=1;i<n;i++)

    {

        int xx,yy; xx=read(); yy=read();

        add(xx,yy); add(yy,xx);

    }

    dfs1(1,1); memset(f,0,sizeof f); dfs2(1);

    //build_tree(root,1,n);

    for (int i=1;i<=n-1;i++) tadd(ord[i],ord[i+1]);

    qury(root,1,n,a[root].tag);

    for (int i=2;i<=n;i++) ans[ord[i]]--;

    for (int i=1;i<=n;i++) printf("%lld\n",ans[i]);

return 0;

}

猜你喜欢

转载自blog.csdn.net/syh0313/article/details/88885484