求助树上莫队
  • 板块学术版
  • 楼主Others
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/10/4 20:55
  • 上次更新2023/11/4 04:50:22
查看原帖
求助树上莫队
383791
Others楼主2021/10/4 20:55

这道题,样例过了,自己出了几组数据也没有问题,看题目的反馈就很奇怪,翻译过来:

期待 non -1,找到了 -1,这就很迷茫...

#include <bits/stdc++.h>
using namespace std;
const int N=300005,NN=600005;
int n,q,root,a[N],nxt[NN],head[N],to[NN],cnt=0,fa[N],depth[N],top[N],sze[N],son[N];
int ord[NN],pos[N][2],nord,s,op[N],idxx[NN],F,T;
int ccnt[N],blcnt[600],ss,bls,L[600],R[600],idx[N],vis[N],ans[N];
struct node{
	int l,r,x,y,lca,id;
}p[300005];
int qr(){
	int x=0,f=0;
	char c=getchar();
	while(c>'9'||c<'0') f|=(c=='-'),c=getchar();
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return f?-x:x;
}
void add(int x,int y){
	nxt[++cnt]=head[x],head[x]=cnt,to[cnt]=y;
	nxt[++cnt]=head[y],head[y]=cnt,to[cnt]=x;
}
void dfs1(int i){
	ord[++nord]=i;
	pos[i][0]=nord;
	depth[i]=depth[fa[i]]+1;
	sze[i]=1;
	for(int p=head[i];p;p=nxt[p]){
		if(to[p]==fa[i]) continue;
		fa[to[p]]=i;
		dfs1(to[p]);
		sze[i]+=sze[to[p]];
		if(son[i]==0||sze[son[i]]<sze[to[p]]) son[i]=to[p];
	}
	ord[++nord]=i;
	pos[i][1]=nord;
	return ;
} 
void dfs2(int i,int Top){
	top[i]=Top;
	if(son[i]>0) dfs2(son[i],Top);
	for(int p=head[i];p;p=nxt[p]){
		if(to[p]==fa[i]||to[p]==son[i]) continue;
		dfs2(to[p],to[p]);
	} 
	return ; 
}
int getlca(int x,int y){
	while(top[x]!=top[y]){
		if(depth[top[x]]>=depth[top[y]]) x=fa[top[x]];
		else y=fa[top[y]];
	}
	return depth[x]<depth[y]?x:y;
}
bool cmp(node x,node y){
	return idxx[x.l]==idxx[y.l]?x.r<y.r:x.l<y.l;
}
int ask(int x,int y){
	if(idx[x]==idx[y]){
		for(int i=y;i>=x;--i){
			if(ccnt[i]) {
				return i;
			}
		}
		return -1;
	}
	for(int i=y;i>=L[idx[y]];--i) {
		if(ccnt[i]) {
			return i;
		}
	}
	for(int i=idx[y]-1;i>idx[x];--i) {
		if(blcnt[i]){
			for(int j=R[i];j>=L[i];--j){
				if(ccnt[i]) {
					return i;
				}
			}
		}
	}
	for(int i=R[idx[x]];i>=x;--i) {
		if(ccnt[i]) {
			return i;
		}
	}
	return -1;
}
void calc(int x){
	ccnt[x]^=1;
	if(ccnt[x]) ++blcnt[idx[x]];
	else --blcnt[idx[x]];
}
int main() {
	n=qr(),q=qr();
	root=1;
	for(int i=1;i<=n;++i){
		a[i]=qr();
	}
	ss=sqrt(n);
	bls=(n+ss-1)/ss;
	for(int i=1;i<=bls;++i){
		L[i]=R[i-1]+1,R[i]=min(n,ss*i);
		for(int j=L[i];j<=R[i];++j){
			idx[j]=i;
		}
	}
	for(int i=1;i<n;++i){
		F=qr(),T=qr();
		add(F,T);
	}
	dfs1(1),dfs2(1,1);
	for(int i=1;i<=q;++i){
		p[i].id=i;
		F=qr(),T=qr(),p[i].x=qr(),p[i].y=qr();
		if(pos[F][0]>pos[T][0]) swap(F,T);
		int lca=getlca(F,T);
		if(lca!=F){
			p[i].lca=lca;
			p[i].l=pos[F][1],p[i].r=pos[T][0];
		}else{
			p[i].lca=0;
			p[i].l=pos[F][0],p[i].r=pos[T][0];
		}
	}
	s=sqrt(nord);
	for(int i=1;i<=nord;++i){
		idxx[i]=(i+s-1)/s;
	}
	sort(p+1,p+q+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=q;++i){
		while(r<p[i].r) calc(a[ord[++r]]);
		while(l>p[i].l) calc(a[ord[--l]]);
		while(r>p[i].r) calc(a[ord[r--]]);
		while(l<p[i].l) calc(a[ord[l++]]);
		if(p[i].lca) calc(a[p[i].lca]);
		ans[p[i].id]=ask(p[i].x,p[i].y);
		if(p[i].lca) calc(a[p[i].lca]);
	}
	for(int i=1;i<=q;++i){
		printf("%d\n",ans[i]);
	}
	return 0;
}
/*
10 1
1 2 1 5 4 1 5 4 1 2
1 2
1 3
1 4
2 5
5 10
3 9
4 6
6 7
6 8
5 7 3 5

*/

求dalao帮忙调一下(蒟蒻已经调了 n 天了,n>5

2021/10/4 20:55
加载中...