This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
int N,K,Q,T;
int r1;
int r2;
struct Tree
{
int sz;
int root;
vector <int> par;
int cnt;
vector <int> tIn;
vector <int> tOut;
vector <vector <int>> g;
vector <int> depth;
vector <vector <int>> h;
vector <int> distFromRoot;
void buildg()
{
g.resize(N+1);
tIn.resize(N+1);
tOut.resize(N+1);
depth.resize(N+1);
h.resize(N+1);
for(int i=1; i<=N; i++)
h[i].resize(20);
distFromRoot.resize(N+1);
for(int i=1; i<=N; i++)
if(par[i]>=1)
g[par[i]].push_back(i);
}
void dfs(int u)
{
cnt++;
tIn[u]=cnt;
for(int v:g[u])
{
depth[v]=depth[u]+1;
h[v][0]=u;
for(int j=1; (1<<j)<=depth[v]; j++)
h[v][j]=h[h[v][j-1]][j-1];
dfs(v);
}
tOut[u]=cnt;
}
bool inSubtreeOf(int u,int v)
{
return (tIn[v]>=tIn[u] && tOut[v]<=tOut[u]);
}
int lca(int u,int v)
{
if(depth[v]<depth[u])
swap(u,v);
for(int j=19; j>=0; j--)
if((depth[v]-depth[u])&(1<<j))
v=h[v][j];
if(u==v)
return u;
for(int j=19; j>=0; j--)
{
if(h[u][j]!=h[v][j])
{
u=h[u][j];
v=h[v][j];
}
}
return h[u][0];
}
int dist(int u,int v)
{
int l=lca(u,v);
return distFromRoot[u]+distFromRoot[v]-2*distFromRoot[l];
}
} T1,T2;
int L2;
vector <pair <int,int>> g[1000005];
void add(int u,int v)
{
if(L2==0 || T2.depth[u]<T2.depth[L2])
L2=u;
if(T2.depth[v]<T2.depth[L2])
L2=v;
cout<<"? "<<u<<" "<<v<<endl;
int x,y,z,w;
cin>>x>>y>>z>>w;
T1.distFromRoot[v]=T1.distFromRoot[u]+y;
int lca2=T2.lca(u,v);
if(T2.depth[lca2]<T2.depth[L2])
L2=lca2;
g[lca2].push_back(make_pair(u,z));
g[lca2].push_back(make_pair(v,w));
}
int cnt;
void printNodes(int u)
{
if(cnt<K)
cout<<u<<" ";
cnt++;
for(int v:T1.g[u])
printNodes(v);
}
void dfs(int u)
{
for(int v:T1.g[u])
{
if(cnt<K-1)
add(u,v);
cnt++;
dfs(v);
}
}
queue <int> q;
bool viz[1000005];
int dist[1000005];
int main()
{
cin>>N>>K>>Q>>T;
T1.par.resize(N+1);
T2.par.resize(N+1);
for(int i=1; i<=N; i++)
{
cin>>T1.par[i];
if(T1.par[i]==-1)
r1=i;
}
for(int i=1; i<=N; i++)
{
cin>>T2.par[i];
if(T2.par[i]==-1)
r2=i;
}
T1.buildg();
T1.dfs(r1);
T2.buildg();
T2.dfs(r2);
printNodes(r1);
cout<<endl;
cnt=0;
dfs(r1);
cout<<"!"<<endl;
cout.flush();
q.push(L2);
viz[L2]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
for(pair <int,int> edge:g[x])
{
if(viz[edge.first]==0)
{
viz[edge.first]=1;
dist[edge.first]=dist[x]+edge.second;
q.push(edge.first);
}
}
}
while(T--)
{
int p,q;
cin>>p>>q;
int lca1=T1.lca(p,q);
int lca2=T2.lca(p,q);
cout<<T1.distFromRoot[p]+T1.distFromRoot[q]-2*T1.distFromRoot[lca1]<<" "<<dist[p]+dist[q]-2*dist[lca2]<<endl;
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |