萌新求助卡常
查看原帖
萌新求助卡常
332022
ChthollyMeow楼主2022/8/23 21:03

树上莫队+根号平衡,复杂度 O(nn)O(n\sqrt{n})(假设 n,mn,m 同阶)

TLE #7

#pragma GCC optimize("Ofast")

#include<bits/stdc++.h>

#define int long long

using namespace std;

inline int read(){
	int x=0,f=1;char c=getchar();
	for(;(c<'0'||c>'9');c=getchar()){if(c=='-')f=-1;}
	for(;(c>='0'&&c<='9');c=getchar())x=x*10+(c&15);
	return x*f;
}

const int MN=3e5+5;
const int MB=1005;

int n,m,B;
int bl[MN],L[MB],R[MB],sum[MB],c[MN],a[MN];

struct Node{int l,r,id,z,ql,qr;}q[MN];

int st[MN],ed[MN],E[MN<<1];
vector<int>G[MN];

namespace HLD{
	int dep[MN],fa[MN],sz[MN],hson[MN],top[MN];

	void dfs1(int u,int de){
		dep[u]=de,sz[u]=1;
		for(int v:G[u]){
			if(v==fa[u])continue;
			fa[v]=u,dfs1(v,de+1),sz[u]+=sz[v];
			if(sz[v]>sz[hson[u]])hson[u]=v;
		}
	}

	int tot=0;
	void dfs2(int u,int tp){
		top[u]=tp;st[u]=++tot;E[tot]=u;
		if(hson[u])dfs2(hson[u],tp);
		for(int v:G[u]){
			if(v==fa[u]||v==hson[u])continue;
			dfs2(v,v);
		}
		ed[u]=++tot;E[tot]=u;
	}

	int LCA(int u,int v){
		while(top[v]!=top[u]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
			u=fa[top[u]];
		}
		if(dep[u]>dep[v])swap(u,v);
		return u;
	}
};

void modify(int x){
	c[x]^=1;
	if(c[x])sum[bl[x]]++;
	else sum[bl[x]]--;
}

int get(int l,int r){
	if(bl[l]==bl[r]){
		for(int i=l;i<=r;i++)if(c[i])return i;
		return -1;
	}
	for(int i=l;i<=R[bl[l]];i++)if(c[i])return i;
	for(int i=L[bl[r]];i<=r;i++)if(c[i])return i;
	for(int i=bl[l]+1;i<=bl[r]-1;i++){
		if(sum[i]==0)continue;
		for(int j=L[i];j<=R[i];j++)if(c[j])return j;
	}
	return -1;
}

int ans[MN],len;

signed main(void){

#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
#endif

	n=read(),m=read();B=(int)(sqrt(n));memset(L,63,sizeof(L));
	for(int i=1;i<=n;i++)a[i]=read(),bl[i]=(i-1)/B+1;
	for(int i=1;i<=n;i++)L[bl[i]]=min(L[bl[i]],i),R[bl[i]]=max(R[bl[i]],i);
	for(int i=2;i<=n;i++){
		int u=read(),v=read();
		G[u].push_back(v),G[v].push_back(u);
	}

	// for(int i=1;i<=bl[n];i++)cout<<L[i]<<" ";puts("");
	// for(int i=1;i<=bl[n];i++)cout<<R[i]<<" ";puts("");

	HLD::dfs1(1,1),HLD::dfs2(1,1);
	// puts("ok");
	for(int i=1;i<=m;i++){
		int u=read(),v=read(),l=read(),r=read();
		q[i].ql=l,q[i].qr=r,q[i].id=i;
		if(st[u]>st[v])swap(u,v);
		if(ed[u]>ed[v])q[i].l=st[u],q[i].r=st[v];
		else{
			int z=HLD::LCA(u,v);
			q[i].z=z,q[i].l=ed[u],q[i].r=st[v];
		}
	}
	// puts("ok");

	len=(int)(n*2/(int)(sqrt(m)));
	sort(q+1,q+m+1,[](const Node &x,const Node &y){
		int bx=(x.l-1)/len+1,by=(y.l-1)/len+1;
		if(bx!=by)return bx<by;
		return (bx&1)?(x.r<y.r):(x.r>y.r);
	});

	// puts("ok");
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		int ql=q[i].l,qr=q[i].r;
		// cout<<ql<<" "<<qr<<endl;
		while(l>ql)modify(a[E[--l]]);
		while(r<qr)modify(a[E[++r]]);
		while(l<ql)modify(a[E[l++]]);
		while(r>qr)modify(a[E[r--]]);
		if(q[i].z)modify(a[q[i].z]);
		ans[q[i].id]=get(q[i].ql,q[i].qr);
		if(q[i].z)modify(a[q[i].z]);
	}

	for(int i=1;i<=m;i++)cout<<ans[i]<<'\n';

	return 0;
}
2022/8/23 21:03
加载中...