1 Commits
main ... 04_02

Author SHA1 Message Date
unlockable
3d4ad11b89 ac! 2023-11-05 15:54:51 +08:00

View File

@@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <vector>
#define DEAD false #define DEAD false
#define ALIVE true #define ALIVE true
// 'Natural count' is the name of the node when all the nodes in the tree is // 'Natural count' is the name of the node when all the nodes in the tree is
@@ -9,144 +10,91 @@ long long dead_nodes_num[105] = {0};
int total_dead_nodes = 0; int total_dead_nodes = 0;
long long target_nodes_num[105] = {0}; long long target_nodes_num[105] = {0};
int total_target_nodes = 0; int total_target_nodes = 0;
long long max_spawned_num = 0;
struct SeveralContinuedDeadNode { struct Layer {
bool status; long long start_num;
long long length; // Caution that when status == dead and length == 1, the node itself is alive. long long end_num;
std::vector<long long> dead_nodes;
}; };
struct SearchResult { Layer tree[150] = {0};
int next_ans_pos; // pos in the ans[] array.
long long count_in_father_line; // natural count.
};
SearchResult find_node(long long target, long long start_num, int next_dead_node_num_ptr, void create_tree(long long start_num, long long prev_alive, int layer, int next_dead_node_ptr) {
SeveralContinuedDeadNode *upper_line, long long upper_line_segment_count, tree[layer].start_num = start_num;
int layer) { prev_alive *= 2;
long long spawned_node_max_num = start_num - 1; tree[layer].end_num = start_num + prev_alive - 1;
long long segment_count = upper_line_segment_count; while (next_dead_node_ptr < total_dead_nodes &&
SeveralContinuedDeadNode current_line_node[200] = {0}; dead_nodes_num[next_dead_node_ptr] <= tree[layer].end_num) {
long long current_line_len = 0; tree[layer].dead_nodes.push_back(dead_nodes_num[next_dead_node_ptr++]);
bool all_dead = true; prev_alive--;
}
// Spawing all the nodes in current line if (prev_alive == 0 || tree[layer].end_num >= target_nodes_num[total_target_nodes - 1]) {
for (int upper_line_iter = 0; upper_line_iter < upper_line_segment_count; upper_line_iter++) { max_spawned_num = tree[layer].end_num;
if (upper_line[upper_line_iter].status == DEAD) { return;
current_line_node[current_line_len] = upper_line[upper_line_iter];
current_line_node[current_line_len].length *= 2;
current_line_len++;
}
else {
all_dead = false;
long long total_spawned_after = spawned_node_max_num + upper_line[upper_line_iter].length * 2;
while (dead_nodes_num[next_dead_node_num_ptr] <= total_spawned_after &&
next_dead_node_num_ptr < total_dead_nodes) {
if (dead_nodes_num[next_dead_node_num_ptr] - spawned_node_max_num > 1) {
current_line_node[current_line_len] = SeveralContinuedDeadNode{
ALIVE, dead_nodes_num[next_dead_node_num_ptr] - spawned_node_max_num - 1};
current_line_len++; // things before this new dead node
}
current_line_node[current_line_len] =
SeveralContinuedDeadNode{DEAD, 1}; // this new dead node
current_line_len++;
spawned_node_max_num = dead_nodes_num[next_dead_node_num_ptr]; // we now spawned to
// this dead node.
next_dead_node_num_ptr++;
}
if (spawned_node_max_num < total_spawned_after) {
current_line_node[current_line_len] =
SeveralContinuedDeadNode{ALIVE, total_spawned_after - spawned_node_max_num};
current_line_len++;
}
spawned_node_max_num = total_spawned_after;
}
} }
if (all_dead) { create_tree(tree[layer].end_num + 1, prev_alive, layer + 1, next_dead_node_ptr);
return SearchResult{1, -1}; }
void find_ans(long long target, int layer) {
ans[layer] = target;
if (layer == 1) {
return;
} }
long long count_in_layer = (target - tree[layer].start_num) / 2;
if (target <= spawned_node_max_num) { for (int i = 0; i < tree[layer - 1].dead_nodes.size(); i++) {
ans[0] = target; if (count_in_layer < tree[layer - 1].dead_nodes[i] - tree[layer - 1].start_num - i) {
long long natural_pos = -1, num = start_num - 1; find_ans(tree[layer - 1].start_num + i + count_in_layer, layer - 1);
for (int i = 0; i < current_line_len; i++) { return;
if (current_line_node[i].status == DEAD) {
natural_pos += current_line_node[i].length;
num += (current_line_node[i].length == 1);
if (num == target) {
return SearchResult{1, natural_pos / 2};
}
continue;
}
// Now deal with alive nodes
if (num + current_line_node[i].length < target) {
natural_pos += current_line_node[i].length;
num += current_line_node[i].length;
}
else {
// if we made it here, then the target > num + current_line_node[i].length
return SearchResult{1, (natural_pos + target - num) / 2};
}
} }
return SearchResult{1, -1};
}
else {
SearchResult current_line_pos =
find_node(target, spawned_node_max_num + 1, next_dead_node_num_ptr, current_line_node,
current_line_len, layer + 1);
if (current_line_pos.count_in_father_line < 0) {
// The path does not exist.
return SearchResult{1, -1};
}
long long natural_count = -1, num = start_num - 1;
for (int i = 0; i < current_line_len; i++) {
natural_count += current_line_node[i].length;
if (current_line_node[i].status == ALIVE || current_line_node[i].length == 1) {
num += current_line_node[i].length;
}
if (natural_count >= current_line_pos.count_in_father_line) {
num -= natural_count - current_line_pos.count_in_father_line;
ans[current_line_pos.next_ans_pos++] = num;
break;
}
}
return SearchResult{current_line_pos.next_ans_pos,
current_line_pos.count_in_father_line / 2};
} }
// til the end_num
find_ans(tree[layer - 1].start_num + tree[layer - 1].dead_nodes.size() + count_in_layer,
layer - 1);
} }
int main() { int main() {
scanf("%d %d", &total_dead_nodes, &total_target_nodes); scanf("%d %d", &total_dead_nodes, &total_target_nodes);
for (int i = 0; i < total_dead_nodes; i++) { for (int i = 0; i < total_dead_nodes; i++) {
scanf("%d", &dead_nodes_num[i]); scanf("%lld", &dead_nodes_num[i]);
} }
for (int i = 0; i < total_target_nodes; i++) {
scanf("%lld", &target_nodes_num[i]);
}
tree[1].start_num = 1;
tree[1].end_num = 1;
if (dead_nodes_num[0] == 1) { if (dead_nodes_num[0] == 1) {
for (int i = 0; i < total_target_nodes; i++) { for (int i = 0; i < total_target_nodes; i++) {
printf("0\n"); if (target_nodes_num[i] == 1) {
} printf("1\n"); //
}
else {
long long current_target = 0;
SeveralContinuedDeadNode firstline = SeveralContinuedDeadNode{ALIVE, 1};
for (int i = 0; i < total_target_nodes; i++) {
scanf("%lld", &current_target);
SearchResult result = find_node(current_target, 2, 0, &firstline, 1, 2);
if (result.count_in_father_line == -1) {
printf("0\n");
} }
else { else {
printf("1 "); printf("0\n");
for (int j = result.next_ans_pos - 1; j >= 0; j--) {
printf("%d ", ans[j]);
}
printf("\n");
} }
} }
return 0;
}
create_tree(2, 1, 2, 0);
// printf("Max spawn: %lld\n", max_spawned_num);
for (int i = 0; i < total_target_nodes; i++) {
if (target_nodes_num[i] > max_spawned_num) {
printf("0\n");
continue;
}
int layer_pos = 1;
while (tree[layer_pos].end_num < target_nodes_num[i]) {
layer_pos++;
}
find_ans(target_nodes_num[i], layer_pos);
for (int j = 1; j <= layer_pos; j++) {
printf("%lld ", ans[j]);
}
printf("\n");
} }
return 0; return 0;