为什么这题开1e5空间会爆
查看原帖
为什么这题开1e5空间会爆
148406
caocao11楼主2021/9/13 16:26

如题。

#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了。

2021/9/13 16:26
加载中...