// heiy ... ye rooze jadid ...
#include <bits/stdc++.h>
//#pragma GCC optimize("O3")
using namespace std;
typedef long long ll;
#define all(x) x.begin(), x.end()
#define pb push_back
#define fi first
#define se second
const int maxn5 = 1e6 + 10;
const int maxnt = 1e6 + 10;
const int lg = 21;
int h[maxn5], ans[maxn5], dis[maxn5], out[maxn5];
vector <pair<int, int>> adj[maxn5];
int par[lg + 1][maxn5];
pair<int, int> pr[maxn5], have[maxn5];
int st[maxn5], ti = 0;
vector <int> av, adj1[maxn5], adj2[maxn5];
bool mark[maxn5];
int st1[maxn5], st2[maxn5], ti1 = 0, ti2 = 0;
int dd1[maxn5], dd2[maxn5], dd3[maxn5], dd4[maxn5];
int q1[maxn5], q2[maxn5], dp1[maxn5], dp2[maxn5], last1[maxn5], last2[maxn5];
int pre1[maxn5], pre2[maxn5], a[maxn5];
void dfs_lca(int v){
st[v] = ++ti;
if(par[0][v] == -1)
dis[v] = 0;
for(int i = 1; i < lg && par[i - 1][v] != -1; i++)
par[i][v] = par[i - 1][par[i - 1][v]];
//cout << "aha " << v << ' ' << h[v] << ' ' << dis[v] << ' ' << par[0][v] << endl;
for(auto [u, len] : adj[v]){
h[u] = h[v] + 1;
dis[u] = dis[v] + len;
par[0][u] = v;
dfs_lca(u);
}
}
inline int lca(int a, int b){
if(h[a] < h[b])
swap(a, b);
int d = h[a] - h[b];
//cout << "ok " << a << ' ' << b << ' ' << d << ' ' << h[a] << ' ' << h[b] << endl;
for(int i = 0; i < lg; i++) if((d >> i)&1)
a = par[i][a];
//cout << "and " << a << endl;
if(a == b)
return a;
for(int i = lg - 1; i >= 0; i--) if(par[i][a] != par[i][b]){
a = par[i][a];
b = par[i][b];
}
return par[0][a];
}
inline void solve(int n, int k, int t, int root){
memset(par, -1, sizeof par);
memset(mark, false, sizeof mark);
ti = 0;
h[root] = dis[root] = 0;
dfs_lca(root);
for(int i = 0; i < n; i++){
pr[i].fi = -1;
pr[i].se = 0;
}
av.clear(); av.pb(have[0].se);
for(int i = 1; i < k; i++){
int v = have[i - 1].se, u = have[i].se;
int c = lca(have[i - 1].se, have[i].se);
int d1 = dd1[i], d2 = dd2[i];
//cout << "its " << u << ' ' << v << ' ' << c << endl;
mark[u] = mark[v] = mark[c] = true;
while(av.size() && h[c] < h[av.back()]){
v = av.back();
av.pop_back();
d1 -= pr[v].se;
//cout << "pop " << v << endl;
}
//cout << "ok " << v << ' ' << u << ' ' << c << ' ' << d1 << endl;
if(v != c){
d1 += pr[v].se;
if(av.size() && av.back() != c){
pr[c] = {av.back(), pr[v].se - d1};
//cout << "oh par " << pr[c].fi << ' ' << pr[c].se << endl;
}
if(av.empty() || av.back() != c)
av.pb(c);
pr[v] = {c, d1};
//cout << "here " << d1 << endl;
}
if(c != u){
av.pb(u);
pr[u] = {c, d2};
}
}
for(int i = 0; i < n; i++)
adj[i].clear();
for(int i = 0; i < n; i++){
if(pr[i].fi != -1)
adj[pr[i].fi].pb({i, pr[i].se});
else if(mark[i])
root = i;
}
//cout << "SECOND TREE " << endl;
memset(par, -1, sizeof par);
h[root] = 0;
//return 0;
dfs_lca(root);
for(int i = 0; i < t; i++){
int a = q1[i], b = q2[i];
int c = lca(a, b);
ans[i] = dis[a] + dis[b] - 2 * dis[c];
}
}
void dfs_st2(int v){
st2[v] = ti2++;
for(auto u : adj2[v])
dfs_st2(u);
}
void dfs_st1(int v){
st1[v] = ti1++;
for(auto u : adj1[v])
dfs_st1(u);
}
inline bool cmp(int i, int j){return st1[i] < st1[j];}
int main(){
ios_base::sync_with_stdio(false); cin.tie(0);
int n, k, q, t; cin >> n >> k >> q >> t;
int root1, root2;
for(int i = 0; i < n; i++){
int p; cin >> p;
p--;
if(p != -2)
adj1[p].pb(i);
else
root1 = i;
}
for(int i = 0; i < n; i++){
int p; cin >> p;
p--;
if(p != -2)
adj2[p].pb(i);
else
root2 = i;
}
dfs_st1(root1);
dfs_st2(root2);
if(q == 2 * k - 2){
for(int i = 0; i < k; i++)
cout << i + 1 << ' ';
cout << endl;
for(int i = 0; i < k; i++)
have[i] = {st1[i], i};
sort(have, have + k);
for(int i = 1; i < k; i++){
cout << "? " << have[i - 1].se + 1 << ' ' << have[i].se + 1 << '\n';
}
for(int i = 0; i < k; i++)
have[i] = {st2[i], i};
sort(have, have + k);
for(int i = 1; i < k; i++){
cout << "? " << have[i - 1].se + 1 << ' ' << have[i].se + 1 << '\n';
}
cout << "!" << endl;
for(int i = 1; i <= 2 * k - 2; i++)
cin >> dd1[i] >> dd2[i] >> dd3[i] >> dd4[i];
for(int i = 0; i < t; i++){
cin >> q1[i] >> q2[i];
q1[i]--; q2[i]--;
}
//return 0;
for(int i = 0; i < t; i++)
cout << 0 << ' ' << 0 << '\n';
cout << endl;
return 0;
for(int i = 0; i < n; i++){
adj[i].clear();
for(auto u : adj1[i])
adj[i].pb({u, 1});
}
solve(n, k, t, root1);
for(int i = 0; i < t; i++)
out[i] = ans[i];
for(int i = 0; i < n; i++){
adj[i].clear();
for(auto u : adj2[i])
adj[i].pb({u, 1});
}
for(int i = 1; i < k; i++){
dd1[i] = dd3[i + k - 1];
dd2[i] = dd4[i + k - 1];
}
solve(n, k, t, root2);
for(int i = 0; i < t; i++)
cout << out[i] << ' ' << ans[i] << '\n';
cout << endl;
return 0;
}
return 0;
for(int i = 0; i < n; i++)
a[i] = i;
sort(a, a + n, cmp); // bar hasbe st1
fill(dp1, dp1 + n + 5, 1e9);
fill(dp2, dp2 + n + 5, 1e9);
int ans1 = 0, ans2 = 0;
int good1, good2;
memset(last1, -1, sizeof last1);
memset(last2, -1, sizeof last2);
for(int i = 0; i < n; i++){
int p1 = lower_bound(dp1 + 1, dp1 + n + 3, st2[a[i]]) - dp1;
int p2 = lower_bound(dp2 + 1, dp2 + n + 3, -st2[a[i]]) - dp2;
pre1[i] = last1[p1 - 1];
pre2[i] = last2[p2 - 1];
dp1[p1] = st2[a[i]];
dp2[p2] = -st2[a[i]];
last1[p1] = last2[p2] = i;
if(p1 > ans1){
good1 = i;
ans1 = p1;
}
if(p2 > ans2){
good2 = i;
ans2 = p2;
}
}
//cout << "ok " << ans1 << ' ' << ans2 << endl;
if(max(ans1, ans2) < k)
return 0;
if(ans1 > ans2){
int v = good1;
for(int i = 0; i < k; i++){
have[i] = {0, a[v]};
v = pre1[v];
}
}
else{
int v = good2;
for(int i = 0; i < k; i++){
have[i] = {0, a[v]};
v = pre2[v];
}
}
for(int i = 0; i < k; i++){
cout << have[i].se + 1 << ' ';
}
cout << endl;
for(int i = 1; i < k; i++){
cout << "? " << have[i - 1].se + 1 << ' ' << have[i].se + 1 << '\n';
}
cout << "!" << endl;
for(int i = 1; i < k; i++)
cin >> dd1[i] >> dd2[i] >> dd3[i] >> dd4[i];
for(int i = 0; i < t; i++){
cin >> q1[i] >> q2[i];
q1[i]--; q2[i]--;
}
for(int i = 0; i < n; i++){
adj[i].clear();
for(auto u : adj1[i])
adj[i].pb({u, 1});
}
solve(n, k, t, root1);
for(int i = 0; i < t; i++)
out[i] = ans[i];
for(int i = 0; i < n; i++){
adj[i].clear();
for(auto u : adj2[i])
adj[i].pb({u, 1});
}
for(int i = 1; i < k; i++){
swap(dd1[i], dd3[i]);
swap(dd2[i], dd4[i]);
}
solve(n, k, t, root2);
for(int i = 0; i < t; i++)
cout << out[i] << ' ' << ans[i] << '\n';
cout << endl;
}
/*
9 3 2 3
2 -1 2 1 1 5 1 4 5
9 4 5 5 7 3 -1 3 7
0 3 0 3
3 1 3 1
*/
Compilation message
Main.cpp: In function 'int main()':
Main.cpp:161:12: warning: 'root1' may be used uninitialized in this function [-Wmaybe-uninitialized]
161 | dfs_st1(root1);
| ~~~~~~~^~~~~~~
Main.cpp:162:12: warning: 'root2' may be used uninitialized in this function [-Wmaybe-uninitialized]
162 | dfs_st2(root2);
| ~~~~~~~^~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
543 ms |
114700 KB |
Unexpected end of file - int32 expected |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
632 ms |
119080 KB |
Execution killed with signal 13 |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
541 ms |
114696 KB |
Unexpected end of file - int32 expected |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
1152 ms |
158576 KB |
Unexpected end of file - int32 expected |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
1381 ms |
158504 KB |
Unexpected end of file - int32 expected |
2 |
Halted |
0 ms |
0 KB |
- |