这个线段树合并为什么一直爆栈啊
查看原帖
这个线段树合并为什么一直爆栈啊
399150
ShunpowerSHUN理成张楼主2024/1/22 20:49

RT,按照题解和讨论区的思路写的,垃圾回收+先走重儿子。

卡了一下午了 test 131(一条长度为 n=106n=10^6 的链)都一直 RE 报 STATUS_STACK_OVERFLOW,经过特判发现连 binary_search 和 merge 的门都没摸到,在 dfs 里面遍历树就直接 RE 了。Link

这到底是为啥啊?????

//Author:Leftist / Shunpower
//Spade Su & Griffin BAO
//May the force be with you and me.
#include <bits/stdc++.h>
#define ET return 0
#define fi first
#define se second
#define mp make_pair
#define pb emplace_back
#define ll long long
#define ull unsigned long long
#define inf INT_MAX
#define uinf INT_MIN
#define pii pair<int,int>
#define pll pair<ll,ll>
#define debug puts("--------Chery AK IOI--------");
#define Yes cout<<"Yes"<<endl;
#define No cout<<"No"<<endl;
#define pt puts("")
#define fr1(i,a,b) for(int i=a;i<=b;i++)
#define fr2(i,a,b) for(int i=a;i>=b;i--)
#define fv(i,p) for(int i=0;i<p.size();i++)
#define ld long double
#define il inline
#define ptc putchar
//Quickly power: ll d=qpow(b,p>>1,k);
//Segment Tree: Memory Limit Excceed
//Segment Tree: Modify()->Pushdown()
//Mod: +M, %M, define int ll
//Mod: Don't use 998244353 instead of 1e9+7 and so on
//Don't solve a problem for too long time.
using namespace std;
const int N=1e6+10;
namespace Shun{
    int lowbit(int x){
        return x&-x;
    }
    template <typename T>
    inline void read(T &x){
       T s=0,w=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){
            if(ch=='-'){
                w=-1;
            }
            ch=getchar();
        }
       while(ch>='0'&&ch<='9'){
            s=s*10+ch-'0';
            ch=getchar();
       }
       x=s*w;
    }
    template <typename T>
    inline void write(T x){
        if(x<0){
            putchar('-');
            x=-x;
        }
        if(x>9){
            write(x/10);
        }
        putchar(x%10+'0');
    }
}
using namespace Shun;
int nxt[N<<1],head[N<<1],edge[N<<1];
int tpt;
void add(int u,int v){
	tpt++;
	nxt[tpt]=head[u];
	head[u]=tpt;
	edge[tpt]=v;
}
int n;
int rt[N],dep[N],siz[N];
int ans[N];
int hson[N];
#define mid (l+r>>1)
struct Segment_Tree{
    int tot,maxn[N<<2],ls[N<<2],rs[N<<2];
    stack <int> st;
    void pushup(int x){
        maxn[x]=max(maxn[ls[x]],maxn[rs[x]]);
    }
    void insert(int &p,int l,int r,int d,int x){
        if(!p){
            if(!st.empty()){
                p=st.top();
                st.pop();
            }
            else{
                tot++;
                p=tot;    
            }
        }
        if(l==r){
            maxn[p]+=x;
            return;
        }
        if(d<=mid){
            insert(ls[p],l,mid,d,x);
        }
        else{
            insert(rs[p],mid+1,r,d,x);
        }
        pushup(p);
    }
    int merge(int x,int y,int l,int r){
        if(!x||!y){
            return x+y;
        }
        if(l==r){
            maxn[x]+=maxn[y];
            st.push(y);
            maxn[y]=ls[y]=rs[y]=0;
            return x;
        }
        ls[x]=merge(ls[x],ls[y],l,mid);
        rs[x]=merge(rs[x],rs[y],mid+1,r);
        st.push(y);
        maxn[y]=ls[y]=rs[y]=0;
        pushup(x);
        return x;
    }
    int binary_search(int p,int l,int r){
        // cerr<<p<<" "<<l<<" "<<r<<endl;
        if(l==r){
            return l;
        }
        if(rs[p]&&(!ls[p]||maxn[rs[p]]>maxn[ls[p]])){
            return binary_search(rs[p],mid+1,r);
        }
        else{
            return binary_search(ls[p],l,mid);
        }
    }
} T;
#undef mid
void init(int x,int fa){
    siz[x]=1;
    int maxn=0;
    for(int i=head[x];~i;i=nxt[i]){
        int y=edge[i];
        if(y==fa){
            continue;
        }
        init(y,x);
        siz[x]+=siz[y];
        if(siz[y]>maxn){
            maxn=siz[y];
            hson[x]=y;
        }
    }
}
void dfs(int x,int fa){
    dep[x]=dep[fa]+1;
    // cerr<<x<<":"<<T.tot<<endl;
    // if(x==1000000&&(n==1000000&&p[2].size()==2&&p[3].size()==2&&p[4].size()==2&&p[5].size()==2)){
    //     cout<<"good"<<endl;
    //     exit(0);
    // }
    if(hson[x]){
        dfs(hson[x],x);
        rt[x]=T.merge(rt[x],rt[hson[x]],1,n);
    }
    for(int i=head[x];~i;i=nxt[i]){
        int y=edge[i];
        if(y==fa||y==hson[x]){
            continue;
        }
        dfs(y,x);
        rt[x]=T.merge(rt[x],rt[y],1,n);
    }
    T.insert(rt[x],1,n,dep[x],1);
    // if(!(n==1000000&&p[2].size()==2&&p[3].size()==2&&p[4].size()==2&&p[5].size()==2)){
    ans[x]=T.binary_search(rt[x],1,n)-dep[x];
    // }
    // else{
    //     cout<<"chery"<<endl;
    //     exit(0);
    // }
}
// #define Griffin zyz
int main(){
#ifdef Griffin
    freopen("hack.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    memset(head,-1,sizeof(head));
    read(n);
    fr1(i,1,n-1){
        int u,v;
        read(u),read(v);
        add(u,v);
        add(v,u);
    }
    init(1,1);
    // cerr<<"!"<<endl;
    dfs(1,1);
    // cerr<<T.tot<<endl;
    // cout<<"!"<<endl;
    fr1(i,1,n){
        write(ans[i]);
        puts("");
    }
    ET;
}
//ETERNAL LOVE FOR Zhang Junhao, Mu Zhicheng and Zuo Hang.
//ALL FOR Zhang Junhao.
2024/1/22 20:49
加载中...