QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#527186#7245. Frank SinatraThe_Shadow_DragonML 0ms0kbC++143.6kb2024-08-22 11:33:592024-08-22 11:34:02

Judging History

你现在查看的是最新测评结果

  • [2024-08-22 11:34:02]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2024-08-22 11:33:59]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct node
{
	int nxt,to;
}e[1000010];
int head[500010],a[500010],top[500010],fa[500010],siz[500010],dep[500010],son[500010],vis[500010],cnt=0;
void add(int u,int v)
{
	cnt++;
	e[cnt].nxt=head[u];
	e[cnt].to=v;
	head[u]=cnt;
}
struct PDS_SMT
{
	int root[500010],rt_sum;
	struct SegmentTree
	{
		int ls,rs,sum,cnt;
	}tree[500010<<5];
	#define lson(rt) tree[rt].ls
	#define rson(rt) tree[rt].rs
	int build_rt()
	{
		rt_sum++;
		return rt_sum;
	}
	void build_tree(int &rt,int l,int r)
	{
		rt=build_rt();
		if(l==r)
		{
			return;
		}
		int mid=(l+r)/2;
		build_tree(lson(rt),l,mid);
		build_tree(rson(rt),mid+1,r);
	}
	void pushup(int rt)
	{
		tree[rt].cnt=tree[lson(rt)].cnt+tree[rson(rt)].cnt;
	}
	void update(int pre,int &rt,int l,int r,int pos)
	{
		rt=build_rt();
		tree[rt]=tree[pre];
		tree[rt].sum++;
		if(l==r)
		{
			tree[rt].cnt=1;
			return;
		}
		int mid=(l+r)/2;
		if(pos<=mid)
		{
			update(lson(pre),lson(rt),l,mid,pos);
		}
		else
		{
			update(rson(pre),rson(rt),mid+1,r,pos);
		}
		pushup(rt);
	}
	int query1(int rt1,int rt2,int rt3,int rt4,int l,int r,int pos)
	{
		if(l==r)
		{
			return tree[rt1].sum+tree[rt2].sum-tree[rt3].sum-tree[rt4].sum;
		}
		int mid=(l+r)/2;
		if(pos<=mid)
		{
			return query1(lson(rt1),lson(rt2),lson(rt3),lson(rt4),l,mid,pos);
		}
		else
		{
			return query1(rson(rt1),rson(rt2),rson(rt3),rson(rt4),mid+1,r,pos);
		}
	}
	int query3(int rt1,int rt2,int rt3,int rt4,int l,int r,int x,int y)
	{
		if(x<=l&&r<=y)
		{
			return tree[rt1].sum+tree[rt2].sum-tree[rt3].sum-tree[rt4].sum;
		}
		int mid=(l+r)/2,ans=0;
		if(x<=mid)
		{
			ans+=query3(lson(rt1),lson(rt2),lson(rt3),lson(rt4),l,mid,x,y);
		}
		if(y>mid)
		{
			ans+=query3(rson(rt1),rson(rt2),rson(rt3),rson(rt4),mid+1,r,x,y);
		}
		return ans;
	}
}T;
void dfs1(int x,int father,int n)
{
	siz[x]=1;
	fa[x]=father;
	dep[x]=dep[father]+1;
	T.update(T.root[father],T.root[x],1,n,a[x]);
	for(int i=head[x];i!=0;i=e[i].nxt)
	{
		if(e[i].to!=father)
		{
			dfs1(e[i].to,x,n);
			siz[x]+=siz[e[i].to];
			son[x]=(siz[e[i].to]>siz[son[x]])?e[i].to:son[x];
		}
	}
}
void dfs2(int x,int id)
{
	top[x]=id;
	if(son[x]!=0)
	{
		dfs2(son[x],id);
		for(int i=head[x];i!=0;i=e[i].nxt)
		{
			if(e[i].to!=fa[x]&&e[i].to!=son[x])
			{
				dfs2(e[i].to,e[i].to);
			}
		}
	}
}
int lca(int u,int v)
{
	while(top[u]!=top[v])
	{
		if(dep[top[u]]>dep[top[v]])
		{
			u=fa[top[u]];
		}
		else
		{
			v=fa[top[v]];
		}
	}
	return (dep[u]>dep[v])?v:u;
}
int query1(int u,int v,int n)
{
	int rt=lca(u,v);
	for(int i=1;i<=n;i++)
	{
		if(T.query1(T.root[u],T.root[v],T.root[rt],T.root[fa[rt]],1,n,i)==0)
		{
			return i;
		}
	}
	return n+1;
}
int query3(int u,int v,int n)
{
	int rt=lca(u,v),l=1,r=n,mid,ans=n+1;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(T.query3(T.root[u],T.root[v],T.root[rt],T.root[fa[rt]],1,n,1,mid)==mid)
		{
			l=mid+1;
		}
		else
		{
			r=mid-1;
			ans=mid;
		}
	}
	return ans;
}
int main()
{
	int n,m,u,v,flag=1,i;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		vis[a[i]]++;
		flag&=(vis[a[i]]==1);
	}
	for(i=1;i<=n-1;i++)
	{
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	dfs1(1,0,n);
	dfs2(1,1);
	if(flag==1)
	{
		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&u,&v);
			printf("%d\n",query3(u,v,n));
		}
	}
	else
	{
		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&u,&v);
			printf("%d\n",query1(u,v,n));
		}
	}
	return 0;
}

详细

Test #1:

score: 0
Memory Limit Exceeded

input:

7 6
2 1 1
3 1 2
1 4 0
4 5 1
5 6 3
5 7 4
1 3
4 1
2 4
2 5
3 5
3 7

output:


result: