#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define N 1000000
#define K 21
typedef long long ll;
int n, req;
typedef struct {
int a, b;
ll w;
} edge;
typedef struct{
int ec;
edge e[2*N+2];
int in[N];
} edges;
typedef struct {
int r;
int j[N][K];
int d[N], vis[N];
ll h[N];
edges *ne, *se;
} tree;
tree t1, t2;
int nodes[N], nc;
int ei[N], ec;
void
add_edge(edges *e, int a, int b, ll w)
{
e->e[e->ec++] = (edge){a, b, w};
e->e[e->ec++] = (edge){b, a, -w};
}
int
_sort_edge(const void *a, const void *b)
{
return ((edge *)a)->a - ((edge *)b)->a;
}
void
edges_make(edges *e)
{
int x, y;
x = y = 0;
qsort(e->e, e->ec, sizeof *(e->e), _sort_edge);
while (x < n && y < e->ec) {
if (x <= e->e[y].a)
e->in[x++] = y;
else
++y;
}
while (x < n)
e->in[x++] = e->ec;
}
int
_sort_nodes(const void *a, const void *b)
{
return ei[*(int *)a] - ei[*(int *)b];
}
void
tree_depth_dfs(tree *t, int x, int d)
{
t->d[x] = d;
if (t == &t1)
nodes[nc++] = x;
ei[x] = ec++;
for (int i = t->ne->in[x]; i < t->ne->ec && t->ne->e[i].a == x; ++i) {
if (t->ne->e[i].b == t->j[x][0]) continue;
tree_depth_dfs(t, t->ne->e[i].b, d+1);
}
return;
}
void
tree_init(tree *t, int *p)
{
int i, k;
t->ne = malloc(sizeof *t->ne);
t->se = malloc(sizeof *t->se);
for (i = 0; i < n; ++i) {
--p[i]; t->vis[i] = 0;
if (p[i] == -2) {
t->r = i;
t->j[i][0] = i;
} else {
t->j[i][0] = p[i];
add_edge(t->ne, i, p[i], -1);
}
}
for (k = 1; k < K; ++k)
for (i = 0; i < n; ++i)
t->j[i][k] = t->j[t->j[i][k-1]][k-1];
edges_make(t->ne);
tree_depth_dfs(t, t->r, 0);
}
int
lca(tree *t, int a, int b)
{
if (t->d[a] < t->d[b]) {
a = a + b; b = a - b; a = a - b;
}
for (int k = K-1; k >= 0; --k) {
if (t->d[t->j[a][k]] >= t->d[b])
a = t->j[a][k];
}
assert(t->d[a] == t->d[b]);
if (a == b) return a;
for (int k = K-1; k >= 0; --k) {
if (t->j[a][k] != t->j[b][k]) {
a = t->j[a][k];
b = t->j[b][k];
}
}
return t->j[a][0];
}
void
con_depth(tree *t, int x, ll d)
{
if (t->vis[x]) return;
t->vis[x] = 1;
t->h[x] = d;
for (int i = t->se->in[x]; i < t->se->ec && t->se->e[i].a == x; ++i)
con_depth(t, t->se->e[i].b, d + t->se->e[i].w);
return;
}
ll ans[100000][2];
int
main(int argc, char *argv[])
{
int q, t, i, x, y, z ,w, l;
int p[N];
scanf("%d %d %d %d\n", &n, &req, &q, &t);
for (i = 0; i < n; ++i)
scanf("%d ", &p[i]);
tree_init(&t1, p);
for (i = 0; i < n; ++i)
scanf("%d ", &p[i]);
ec = 0; tree_init(&t2, p);
assert(nc == n);
qsort(nodes, req, sizeof *nodes, _sort_nodes);
for (i = 0; i < req; ++i)
printf("%d ", nodes[i]+1);
puts("");
for (i = 0; i < req-1; ++i) {
printf("? %d %d\n", nodes[i]+1, nodes[i+1]+1);
}
puts("!"); fflush(stdout);
for (i = 0; i < req-1; ++i) {
scanf("%d %d %d %d\n", &x, &y, &z, &w);
l = lca(&t1, nodes[i], nodes[i+1]);
add_edge(t1.se, nodes[i], l, -x);
add_edge(t1.se, nodes[i+1], l, -y);
l = lca(&t2, nodes[i], nodes[i+1]);
add_edge(t2.se, nodes[i], l, -z);
add_edge(t2.se, nodes[i+1], l, -w);
}
edges_make(t1.se);
edges_make(t2.se);
con_depth(&t1, nodes[i], 0);
con_depth(&t2, nodes[i], 0);
for (l = 0; l < t; ++l) {
scanf("%d %d\n", &x, &y); --x; --y;
ans[l][0] = t1.h[x] + t1.h[y] - 2ll * t1.h[lca(&t1, x, y)];
ans[l][1] = t2.h[x] + t2.h[y] - 2ll * t2.h[lca(&t2, x, y)];
}
for (l = 0; l < t; ++l) {
printf("%lld %lld\n", ans[l][0], ans[l][1]);
}
fflush(stdout);
}
Compilation message
Main.c: In function 'main':
Main.c:152:5: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
152 | scanf("%d %d %d %d\n", &n, &req, &q, &t);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.c:155:9: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
155 | scanf("%d ", &p[i]);
| ^~~~~~~~~~~~~~~~~~~
Main.c:159:9: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
159 | scanf("%d ", &p[i]);
| ^~~~~~~~~~~~~~~~~~~
Main.c:176:9: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
176 | scanf("%d %d %d %d\n", &x, &y, &z, &w);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.c:191:9: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
191 | scanf("%d %d\n", &x, &y); --x; --y;
| ^~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
555 ms |
94248 KB |
Time limit exceeded (wall clock) |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
562 ms |
94244 KB |
Time limit exceeded (wall clock) |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
541 ms |
94236 KB |
Time limit exceeded (wall clock) |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1146 ms |
184416 KB |
Time limit exceeded (wall clock) |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1190 ms |
184236 KB |
Time limit exceeded (wall clock) |
2 |
Halted |
0 ms |
0 KB |
- |