关于线段树合并
  • 板块学术版
  • 楼主LINTONG1
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/10 10:30
  • 上次更新2023/11/10 15:00:04
查看原帖
关于线段树合并
684962
LINTONG1楼主2023/11/10 10:30

为什么我少写了个回收节点就t了啊

题目:题目

改前代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-')w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
const int maxn=1e6+5;
struct edge{
    int nex,to;
}tr[maxn<<1];
int head[maxn<<1],cnt;
void add(int u,int v){
    tr[++cnt].nex=head[u];
    tr[cnt].to=v;
    head[u]=cnt;
}

struct tree{
    int ls,rs,sum,mx;
}e[maxn<<3];
int tot;
int st[maxn<<3];
int top;
int get(){
    if(top>0)return st[top--];
    else return ++tot;
}
void insert(int &now,int l,int r,int x,int v){
    now=now?now:get();
    if(l==r){
        e[now].sum+=v; 
        e[now].mx=l;
        return;
    }
    int mid=l+r>>1;
    if(x<=mid)insert(e[now].ls,l,mid,x,v);
    else insert(e[now].rs,mid+1,r,x,v);
    e[now].sum=(e[e[now].ls].sum>=e[e[now].rs].sum)?e[e[now].ls].sum:e[e[now].rs].sum;
    e[now].mx=(e[e[now].ls].sum>=e[e[now].rs].sum)?e[e[now].ls].mx:e[e[now].rs].mx;
}
int n,q,rt[maxn];

int merge(int p,int q,int l,int r){
    if((!p)||(!q))return(!p)?q:p;
    if(l==r){
        e[p].sum+=e[q].sum;
        e[p].mx=l;
        e[q].ls=e[q].rs=e[q].sum=e[q].mx=0;
        st[++top]=q;
        return p;
    }
    int mid=l+r>>1;
    e[p].ls=merge(e[p].ls,e[q].ls,l,mid);
    e[p].rs=merge(e[p].rs,e[q].rs,mid+1,r);
    e[p].sum=(e[e[p].ls].sum>=e[e[p].rs].sum)?e[e[p].ls].sum:e[e[p].rs].sum;
    e[p].mx=(e[e[p].ls].sum>=e[e[p].rs].sum)?e[e[p].ls].mx:e[e[p].rs].mx;
    return p;
}

int ans[maxn];
void solve(int x,int fa,int dep){
    for(int i=head[x];i;i=tr[i].nex){
        int y=tr[i].to;
        if(y==fa)continue;
        solve(y,x,dep+1);
        rt[x]=merge(rt[x],rt[y],1,n);
    }    
    insert(rt[x],1,n,dep,1);
    ans[x]=e[rt[x]].mx-dep;
}

signed main(){
    n=read();
    for(int i=1;i<n;i++){
        int u=read(),v=read();
        add(u,v);add(v,u);
    }
    solve(1,0,1);
    for(int i=1;i<=n;i++){
        printf("%d\n",ans[i]);
    }
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-')w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
const int maxn=1e6+5;
struct edge{
    int nex,to;
}tr[maxn<<1];
int head[maxn<<1],cnt;
void add(int u,int v){
    tr[++cnt].nex=head[u];
    tr[cnt].to=v;
    head[u]=cnt;
}

struct tree{
    int ls,rs,sum,mx;
}e[maxn<<3];
int tot;
int st[maxn<<3];
int top;
int get(){
    if(top>0)return st[top--];
    else return ++tot;
}
void insert(int &now,int l,int r,int x,int v){
    now=now?now:get();
    if(l==r){
        e[now].sum+=v; 
        e[now].mx=l;
        return;
    }
    int mid=l+r>>1;
    if(x<=mid)insert(e[now].ls,l,mid,x,v);
    else insert(e[now].rs,mid+1,r,x,v);
    e[now].sum=(e[e[now].ls].sum>=e[e[now].rs].sum)?e[e[now].ls].sum:e[e[now].rs].sum;
    e[now].mx=(e[e[now].ls].sum>=e[e[now].rs].sum)?e[e[now].ls].mx:e[e[now].rs].mx;
}
int n,q,rt[maxn];

int merge(int p,int q,int l,int r){
    if((!p)||(!q))return(!p)?q:p;
    if(l==r){
        e[p].sum+=e[q].sum;
        e[p].mx=l;
        e[q].ls=e[q].rs=e[q].sum=e[q].mx=0;
        st[++top]=q;
        return p;
    }
    int mid=l+r>>1;
    e[p].ls=merge(e[p].ls,e[q].ls,l,mid);
    e[p].rs=merge(e[p].rs,e[q].rs,mid+1,r);
    e[p].sum=(e[e[p].ls].sum>=e[e[p].rs].sum)?e[e[p].ls].sum:e[e[p].rs].sum;
    e[p].mx=(e[e[p].ls].sum>=e[e[p].rs].sum)?e[e[p].ls].mx:e[e[p].rs].mx;
    e[q].ls=e[q].rs=e[q].sum=e[q].mx=0;
    st[++top]=q;//就这里多加了个节点回收
    return p;
}

int ans[maxn];
void solve(int x,int fa,int dep){
    for(int i=head[x];i;i=tr[i].nex){
        int y=tr[i].to;
        if(y==fa)continue;
        solve(y,x,dep+1);
        rt[x]=merge(rt[x],rt[y],1,n);
    }    
    insert(rt[x],1,n,dep,1);
    ans[x]=e[rt[x]].mx-dep;
}

signed main(){
    n=read();
    for(int i=1;i<n;i++){
        int u=read(),v=read();
        add(u,v);add(v,u);
    }
    solve(1,0,1);
    for(int i=1;i<=n;i++){
        printf("%d\n",ans[i]);
    }
}
2023/11/10 10:30
加载中...