0pts 求调 玄关树剖+分块
查看原帖
0pts 求调 玄关树剖+分块
573334
yzkadbq_qwq楼主2024/4/9 19:09
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct edge{
    int v,next;
} e[600001];
int h[300001],tot=0;
void addedge(int u,int v){
    e[++tot].v=v,e[tot].next=h[u],h[u]=tot;
    return;
}
int size[300001],dep[300001],fa[300001],son[300001];
int dfs1(int u,int father){
    size[u]=1;
    son[u]=-1;
    for(int i=h[u];i;i=e[i].next){
        if(e[i].v!=father){
            dep[e[i].v]=dep[u]+1;
            fa[e[i].v]=u;
            size[u]+=dfs1(e[i].v,u);
            if(son[u]==-1 or size[e[i].v]>size[son[u]]) son[u]=e[i].v;
        }
    }
    return size[u];
}
int cnt=0,dfn[300001],top[300001],rnk[300001];
void dfs2(int u,int t){
    top[u]=t;
    dfn[u]=++cnt;
    rnk[cnt]=u;
    if(son[u]==-1) return;
    dfs2(son[u],t);
    for(int i=h[u];i;i=e[i].next){
        if(e[i].v!=son[u] and e[i].v!=fa[u]) dfs2(e[i].v,e[i].v);
    }
    return;
}
int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
        else y=fa[top[y]];
    }
    if(dep[x]>dep[y]) return y;
    else return x;
}
int a[300001],tag[2001],sum[2001],book[2001],bsize,n;
void change(int l,int r){
    int e=min(r,bsize*book[l]);
    for(int i=l;i<=e;i++){
        a[i]++,sum[book[l]]++;
    }
    for(int i=book[l]+1;i<=book[r]-1;i++){
        tag[i]+=bsize;
    }
    if(book[l]!=book[r]){
        for(int i=book[r]*bsize-bsize+1;i<=r;i++){
            a[i]++,sum[book[r]]++;
        }
    }
    return;
}
int query(int l,int r){
    int ans=0,e=min(r,bsize*book[l]);
    for(int i=l;i<=e;i++){
        ans+=a[i],ans+=tag[book[l]];
    }
    for(int i=book[l]+1;i<=book[r]-1;i++){
        ans+=sum[i]+tag[i]*bsize;
    }
    if(book[l]!=book[r]){
        for(int i=book[r]*bsize-bsize+1;i<=r;i++){
            ans+=a[i],ans+=tag[book[r]];
        }
    }
    return ans;
}
int queryt(int x,int y){
    int res=0,fx=top[x],fy=top[y];
    while(fx!=fy){
        if(dep[fx]>dep[fy]) res+=query(dfn[fx],dfn[x]),x=fa[fx];
        else res+=query(dfn[fy],dfn[y]),y=fa[fy];
        fx=top[x],fy=top[y];
    }
    if(dfn[x]<dfn[y]) res+=query(dfn[x],dfn[y]);
    else res+=query(dfn[y],dfn[x]);
    return res;
}
void changet(int x,int y){
    int fx=top[x],fy=top[y];
    while(fx!=fy){
        if(dep[fx]>dep[fy]) change(dfn[fx],dfn[x]),x=fa[fx];
        else change(dfn[fy],dfn[y]),y=fa[fy];
        fx=top[x],fy=top[y];
    }
    if(dfn[x]<dfn[y]) change(dfn[x],dfn[y]);
    else change(dfn[y],dfn[x]);
    return;
}
int g[300001];
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>g[i];
    }
    memset(a,0,sizeof(0));
    bsize=sqrt(n);
    for(int i=1;i<=n;i++){
        book[i]=(i-1)/bsize+1;
    }
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        addedge(u,v),addedge(v,u);
    }
    dfs1(1,0);
    dfs2(1,1);
    for(int i=1;i<n;i++){
        changet(g[i],g[i+1]);
    }
    for(int i=1;i<n;i++){
        cout<<a[dfn[i]]+tag[book[dfn[i]]]<<endl;
    }
    cout<<a[dfn[n]]+tag[book[dfn[n]]]-1<<endl;
    return 0;
}
2024/4/9 19:09
加载中...