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