5 / 5
Feb 21

I did my best to solve this problem. I tried various methods, but I accepted the same problem on another Luogu1, but this problem had a runtime error

I come from China and my English is not good. I have done my best to translate :slight_smile:

#include<bits/stdc++.h>
#define int long long
using namespace std;
//
vector<int>e[222222];
int head[222222];
void add_edge(int x,int y)
{
	e[x].push_back(y);
	e[y].push_back(x);
}
//
int cnt;
struct node1{
	int l,r,v;
}tr[222222];
void build(node1 &root,int l,int r)
{
	root.v=0;
	if(l==r)
	{
		return;
	}
	int mid=(l+r)/2;
	build(tr[root.l=++cnt],l,mid);
	build(tr[root.r=++cnt],mid+1,r);
}
int rts;
int a[222222];
void change(node1 rt1,node1 &rt2,int l,int rr,int x)
{
	rt2.v=rt1.v+1;
	if(l==rr)
	{
		return;
	}
	int mid=(l+rr)/2;
	if(x<=mid)
	{
		change(tr[rt1.l],tr[rt2.l=++cnt],l,mid,x);
		rt2.r=rt1.r;
	}
	else
	{
		change(tr[rt1.r],tr[rt2.r=++cnt],mid+1,rr,x);
		rt2.l=rt1.l;
	}
}
int sum(node1 rt1,node1 rt2,node1 rt3,node1 rt4,int l,int rr,int x)
{
	if(l==rr)
	{
		return l;
	}
	int ss=tr[rt1.l].v+tr[rt2.l].v-tr[rt3.l].v-tr[rt4.l].v,mid=(l+rr)/2;
	if(x<=ss)
	{
		return sum(tr[rt1.l],tr[rt2.l],tr[rt3.l],tr[rt4.l],l,mid,x);
	}
	else
	{
		return sum(tr[rt1.r],tr[rt2.r],tr[rt3.r],tr[rt4.r],mid+1,rr,x-ss);
	}
}
int dep[111111];
int st[111111][22];
int lca(int x,int y)
{
	if(dep[x]>dep[y])
	{
		swap(x,y);
	}
	for(int i=18;i>=0;i--)
	{
		if(dep[st[y][i]]>=dep[x])
		{
			y=st[y][i];
		}
	}
	if(x==y)
	{
		return x;
	}
	for(int i=18;i>=0;i--)
	{
		if(st[y][i]!=st[x][i])
		{
			x=st[x][i];
			y=st[y][i];
		}
	}
	return st[y][0];
}
int n,m;
int aa[111111],b[111111];
int b_len;
void dfs(int x,int fa)
{
	change(tr[head[fa]],tr[head[x]=++cnt],1,b_len,(lower_bound(b+1,b+1+b_len,aa[x])-b));
	st[x][0]=fa;
	dep[x]=dep[fa]+1;
	for(int i=1;i<=18;i++)
	{
		st[x][i]=st[st[x][i-1]][i-1];
	}
	// for(auto y:e[x])
	for(vector<int>::iterator i=e[x].begin();i!=e[x].end();i++)
	{
		int y=*i;
		if(y==fa)
		{
			continue;
		}
		dfs(y,x);
	}
}
int last=0;
signed main()
{
	// cin>>n>>m;
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)
	{
		// cin>>aa[i];
		scanf("%lld",&aa[i]);
		b[i]=aa[i];
	}
	sort(b+1,b+1+n);
	b_len=unique(b+1,b+n+1)-(b+1);
	build(tr[head[0]=++cnt],1,b_len);
	for(int i=1,x,y;i<n;i++)
	{
		// cin>>x>>y;
		scanf("%lld%lld",&x,&y);
		add_edge(x,y);
		add_edge(y,x);
	}
	dfs(1,0);
	for(int i=1,x,y,z;i<=m;i++)
	{
		// cin>>x>>y>>z;
		scanf("%lld%lld%lld",&x,&y,&z);
		int la=lca(x,y);
		// cout<<b[sum(tr[head[x]],tr[head[y]],tr[head[la]],tr[head[st[la][0]]],1,b_len,z)]<<'\n';
		printf("%lld\n",b[sum(tr[head[x]],tr[head[y]],tr[head[la]],tr[head[st[la][0]]],1,b_len,z)]);
	}
}
  • created

    Feb 19
  • last reply

    Feb 20
  • 4

    replies

  • 120

    views

  • 2

    users

  • 2

    links

I’ve not solved this problem, and am far from expert in C or C++, but aren’t you using the longint format %lld in the scanf when reading ints?

@simes

The second line can convert all ing types to long long (long int) at compile time. Many people like to write this way, although it may cause MLE issues