为什么这题开1e5空间会爆

P6626 [省选联考 2020 B 卷] 消息传递

caocao11 @ 2021-09-13 16:26:41

如题。

#include<bits/stdc++.h>
#define ll long long
#define ri register int
using namespace std;
int read(){
    int res=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-f;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        res=(res<<1)+(res<<3)+ch-'0';
        ch=getchar();
    }
    return res*f;
}
const int N=1e5+5;
struct asd{
    int len,id;
};
struct qq{
    int next,to;
}a[N<<1];
int head[N],siz[N],maxx[N],cnt[N],sta[N][2],ans[N],top,num,sum,rt;
bool vis[N];
vector<asd>q[N];
void add(int x,int y){
    a[++num].next=head[x];
    head[x]=num;
    a[num].to=y;
}
void getr(int p,int fa){
    siz[p]=1;maxx[p]=0;
    for(int i=head[p];i;i=a[i].next){
        if(a[i].to!=fa&&!vis[a[i].to]){
            getr(a[i].to,p);
            siz[p]+=siz[a[i].to];
            maxx[p]=max(maxx[p],siz[a[i].to]);
        }
    }
    maxx[p]=max(maxx[p],sum-siz[p]);
    if(maxx[p]<maxx[rt]) rt=p;
}
void dfs(int p,int fa,int ss,int v){
    cnt[ss]+=v;
    for(int i=head[p];i;i=a[i].next)
        if(a[i].to!=fa&&!vis[a[i].to])
            dfs(a[i].to,p,ss+1,v);
}
void work(int p,int fa,int ss,int v){
    cnt[ss]+=v;
    for(int i=0;i<q[p].size();i++){
        sta[++top][0]=q[p][i].len-ss;
        sta[top][1]=q[p][i].id;
    }
    for(int i=head[p];i;i=a[i].next)
        if(a[i].to!=fa&&!vis[a[i].to])
            work(a[i].to,p,ss+1,v);
}
void build(int p){
    vis[p]=1;
    dfs(p,0,0,1);
    for(int i=0;i<q[p].size();i++)
        ans[q[p][i].id]+=cnt[q[p][i].len];
    for(int i=head[p];i;i=a[i].next){
        if(vis[a[i].to]) continue;
        top=0;
        work(a[i].to,0,1,-1);
        for(int j=1;j<=top;j++)
            if(sta[j][0]>=0)
                ans[sta[j][1]]+=cnt[sta[j][0]];
        work(a[i].to,0,1,1);
    }
    dfs(p,0,0,-1);
    for(int i=head[p];i;i=a[i].next){
        if(vis[a[i].to]) continue;
        rt=0;sum=siz[a[i].to];
        getr(a[i].to,p);
        getr(rt,p);
        build(rt);
    }
}
int main(){
    int i,j,k,l,n,m,t;
    t=read();
    while(t--){
        n=read();m=read();
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
        memset(ans,0,sizeof(ans));
        memset(cnt,0,sizeof(cnt));
        num=0;
        for(i=1;i<=n;i++) q[i].clear();
        for(i=1;i<n;i++){
            k=read();l=read();
            add(k,l);add(l,k);
        }
        for(i=1;i<=m;i++){
            k=read();l=read();
            q[k].push_back((asd){l,i});
        }
        maxx[rt=0]=1e9;sum=n;
        getr(1,0);
        getr(rt,0);
        build(1);
        for(i=1;i<=m;i++) printf("%d\n",ans[i]);
    }
    return 0;
}

上面这份代码会RE,但N改成2e5就AC了。


by chrisDLkk @ 2023-11-18 15:02:35

测评端的?吧/


|