求助
查看原帖
求助
80953
Moral_and_Law楼主2020/10/19 20:48

RT 树链剖分+线段树

不懂为何我MLE,将数组开大四倍后反而AC了。求助

#include <bits/stdc++.h>
#define N 100010
#define inf 998244353
using namespace std;
int n,q,tot,cnt;
int top[N],col[N],fa[N],son[N],siz[N],dfn[N],id[N];
int num[N*2],sum=1,to[2*N],nex[2*N],head[N];
void add(int u,int v){to[++tot]=v;nex[tot]=head[u];head[u]=tot;}
void dfs1(int u){
	int i;siz[u]=1;
	for(i=head[u];i;i=nex[i]){
		int v=to[i];if(v==fa[u]) continue;
		fa[v]=u;dfs1(v);siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int f){
	dfn[++cnt]=u;id[u]=cnt;top[u]=f;
	if(!son[u]) return ;
	dfs2(son[u],f);
	for(int i=head[u];i;i=nex[i]){
		int v=to[i];
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
int build(int k,int l,int r){
	if(!k) k=++sum;
	if(l==r){num[k]=inf;return k;}
	int mid=l+r>>1;num[k]=inf;
	build(k<<1,l,mid);build(k<<1|1,mid+1,r);
	return k;
}
void modify(int k,int l,int r,int x,int v){
	if(l==r){num[k]=v;return ;}
	int mid=l+r>>1;
	if(x<=mid) modify(k<<1,l,mid,x,v);
	else modify(k<<1|1,mid+1,r,x,v);
	num[k]=min(num[k<<1],num[k<<1|1]);
}
int query(int k,int l,int r,int x,int y){
	if(x<=l&&r<=y) return num[k];
	int mid=l+r>>1,res=inf;
	if(x<=mid) res=min(res,query(k<<1,l,mid,x,y));
	if(y>mid) res=min(res,query(k<<1|1,mid+1,r,x,y));
	return res;
}
int main(){
	int i,j;scanf("%d%d",&n,&q);
	for(i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}dfs1(1);dfs2(1,1);
	build(1,1,n);
	while(q--){
		int op,x;scanf("%d%d",&op,&x);
		if(op==0){
			col[x]^=1;
			if(!col[x]) modify(1,1,n,id[x],inf);
			else modify(1,1,n,id[x],id[x]);
		}
		else{
			int ans=inf;
			while(top[x]!=1){
				ans=min(ans,query(1,1,n,id[top[x]],id[x]));
				x=fa[top[x]];
			}ans=min(ans,query(1,1,n,id[1],id[x]));
			printf("%d\n",ans==inf ? -1:dfn[ans]);
		}
	}
	return 0;
}

以上代码MLE

记录:https://www.luogu.com.cn/record/40117425

将上面宏定义的N改为400010反而AC

记录:https://www.luogu.com.cn/record/40119074

真诚救助大佬解惑。orz

2020/10/19 20:48
加载中...