Removed unrelated old stuff that is completely unrelated now

This commit is contained in:
Андреев Григорий 2025-12-23 22:51:36 +03:00
parent 19f92d9207
commit 1328d194be
3 changed files with 0 additions and 659 deletions

View File

@ -1,68 +0,0 @@
/* We switch on the light */
#include "../../../l1_5/core/stringsearch.h"
#include "../../../l1_5/core/input_olproga.h"
#include "../../../../gen/l1/VecAndSpan_VecU64.h"
#include "../../../../gen/l1/VecAndSpan_U64.h"
// Aborts on errors
U64 fast_solution(U64 n, U64 a, U64 b, const VecU8* S){
VecVecU64 Z = VecVecU64_new();
for (size_t i = 0; i < n; i++) {
VecU64 z = z_function(VecU8_span(S, i, n - i));
VecVecU64_append(&Z, z);
}
VecU64 dp = VecU64_new_filled(n + 1, UINT64_MAX);
dp.buf[0] = 0;
for (size_t k = 0; k < n; k++) {
size_t score_here = dp.buf[k];
dp.buf[k + 1] = MIN_U64(dp.buf[k + 1], score_here + a);
size_t lets = 0;
for (size_t sss = 0; sss <= k; sss++) {
size_t before = k - sss;
size_t reach = Z.buf[sss].buf[before];
lets = MAX_U64(lets, MIN_U64(reach, before));
}
for (size_t after = 1; after <= lets; after++) {
dp.buf[k + after] = MIN_U64(dp.buf[k + after], score_here + b);
}
}
return dp.buf[n];
}
U64 correct_solution(U64 n, U64 a, U64 b, const VecU8* S){
VecU64 dp = VecU64_new_filled(n + 1, UINT64_MAX);
dp.buf[0] = 0;
for (size_t i = 1; i <= n; i++) {
dp.buf[i] = dp.buf[i - 1] + a;
for (size_t gb = 1; gb <= i; gb++) {
for (size_t start = 0; start + gb * 2 <= i; gb++) {
for (size_t j = 0; j < gb; j++) {
if (S->buf[start + j] != S->buf[i - gb + j])
goto incorrect;
}
/* It was correct */
dp.buf[i] = MIN_U64(dp.buf[i], dp.buf[i - gb] + b);
incorrect:
continue;
}
}
}
return dp.buf[n];
}
int main(){
U64 n = stdin_read_U64_nofail();
U64 a = stdin_read_U64_nofail();
U64 b = stdin_read_U64_nofail();
VecU8 S = stdin_read_VecU8_nospace();
assert(n != 0 && S.len == n);
assert(n <= 5000);
assert(a <= 5000 && b <= 5000);
printf("%lu\n", fast_solution(n, a, b, &S));
return 0;
}

View File

@ -1,304 +0,0 @@
/* Your death is near */
#include "../../../../gen/l1/VecAndSpan_U8.h"
#include "../../../../gen/l1/VecAndSpan_VecU8.h"
#include "../../../../gen/l1/VecAndSpan_VecU32.h"
#include "../../../../gen/l1/VecAndSpan_S64.h"
#include "../../../../gen/l1/VecAndSpan_U64.h"
// #include "../../../l1_5/core/input_olproga.h"
#include "../../../../gen/l1/OptionU64.h"
#define BUF_SIZE 4096
static unsigned char buf[BUF_SIZE];
static size_t pos = 0, sz = 0;
static int pushback = EOF;
int fast_getc() {
if (pushback != EOF) {
int c = pushback;
pushback = EOF;
return c;
}
if (pos == sz) {
sz = fread(buf, 1, BUF_SIZE, stdin);
pos = 0;
if (sz == 0) return EOF;
}
return (int)buf[pos++];
}
void fast_ungetc(int c) {
if (pushback != EOF) {
abort(); // Multiple pushbacks not supported (not needed in your functions)
}
pushback = c;
}
void stdin_skip_whitespaces() {
while (true) {
int ch = fast_getc();
if (ch == EOF)
return;
if (ch != ' ' && ch != '\t' && ch != '\n') {
fast_ungetc(ch);
break;
}
}
}
// Aborts on error
OptionU64 stdin_read_U64() {
stdin_skip_whitespaces();
U64 x = 0;
int i = 0;
for (;; i++) {
int ch = fast_getc();
if (ch == EOF)
break;
if (!('0' <= ch && ch <= '9')) {
fast_ungetc(ch);
break;
}
U64 d = (U64)(ch - '0');
if (x == 0 && i > 0)
abortf("Bad integer input\n");
if (x > UINT64_MAX / 10)
abortf("Integer input exceeds UINT64_MAX\n");
x *= 10;
if (x > UINT64_MAX - d)
abortf("Integer input exceeds UINT64_MAX\n");
x += d;
}
if (i > 0)
return Some_U64(x);
return None_U64();
}
/* If empty string is returned it means EOF was reached */
NODISCARD VecU8 stdin_read_VecU8_nospace() {
stdin_skip_whitespaces();
VecU8 str = VecU8_new();
while (true) {
int ch = fast_getc();
if (ch == EOF)
break;
if (ch == ' ' || ch == '\t' || ch == '\n') {
fast_ungetc(ch);
break;
}
VecU8_append(&str, ch);
}
return str;
}
// Aborts if non-integer input or EOF was encountered before my integer
U64 stdin_read_U64_nofail() {
OptionU64 x = stdin_read_U64();
if (x.variant == Option_None)
abortf("No number found\n");
return x.some;
}
typedef struct {
U64 suf_link;
U64 ans_up_link;
U64 transition[26];
S64 class_ref;
} I_FishNode;
I_FishNode I_FishNode_new(){
/* C++ is fucking lame*/
return (I_FishNode){.suf_link = 0, .ans_up_link = 0, .transition = {0}, .class_ref = -1};
// return (I_FishNode){.class_ref = -1};
}
#include "../../../../gen/l1/eve/r_alg/VecI_FishNode.h"
typedef struct {
VecS64 next_same_ref_on_strings;
VecI_FishNode nodes;
} Fish;
Fish incomplete_Fish_from_VecU8(SpanVecU8 S){
VecS64 next_same_ref_on_strings = VecS64_new_filled(S.len, -1);
VecI_FishNode nodes = VecI_FishNode_new_reserved(1000001);
VecI_FishNode_append(&nodes, I_FishNode_new());
assert(nodes.buf[0].suf_link == 0 && nodes.buf[0].ans_up_link == 0 && nodes.buf[0].transition[0] == 0);
for (size_t j = 0; j < S.len; j++) {
SpanU8 str = VecU8_to_span(&S.data[j]);
U64 cur = 0; /* cur trie node */
for (size_t i = 0; i < str.len; i++) {
U8 ch = str.data[i];
assert('a' <= ch && ch <= 'z');
U8 d = ch - 'a';
assert(d < 26);
assert(cur < nodes.len);
if (nodes.buf[cur].transition[d] == 0) {
U64 nid = nodes.len;
VecI_FishNode_append(&nodes, I_FishNode_new());
nodes.buf[cur].transition[d] = nid;
}
assert(nodes.buf[cur].transition[d] < nodes.len);
assert(nodes.buf[cur].transition[d] != 0);
cur = nodes.buf[cur].transition[d];
}
if (nodes.buf[cur].class_ref != -1) {
assert(next_same_ref_on_strings.buf[j] == -1);
next_same_ref_on_strings.buf[j] = nodes.buf[cur].class_ref;
}
nodes.buf[cur].class_ref = (S64)j;
}
return (Fish){.next_same_ref_on_strings=next_same_ref_on_strings, .nodes=nodes};
}
/* Debug function */
void Fish_debug_print(const Fish* self){
printf("next_same_ref_on_strings:\n");
for (size_t i = 0; i < self->next_same_ref_on_strings.len; i++)
printf("%3ld ", self->next_same_ref_on_strings.buf[i]);
printf("\n");
size_t nc = self->nodes.len;
for (size_t i = 0; i < nc; i++)
printf("=== ");
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("%3ld ", self->nodes.buf[i].class_ref);
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("--- ");
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("%3lu ", self->nodes.buf[i].suf_link);
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("--- ");
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("%3lu ", self->nodes.buf[i].ans_up_link);
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("--- ");
printf("\n");
for (U8 d = 0; d < 26; d++) {
for (size_t i = 0; i < nc; i++) {
printf("%3lu ", self->nodes.buf[i].transition[d]);
}
printf("\n");
}
}
void complete_Fish(Fish* fish){
/* trie unpacked */
size_t nc = fish->nodes.len;
assert(nc >= 1);
/* We first, fields suf_link, ans_up_link are filled with garbage */
// Except for root. Root is already almost initialized
assert(fish->nodes.buf[0].suf_link == 0 && fish->nodes.buf[0].ans_up_link == 0);
// Some transitions are already complete. Those that contain 0 are yet to be filled
// transitions to 0 can't occur naturally in Trie. (Incomplete Fish = Trie)
VecU64 bfs_cur = VecU64_new_zeroinit(1); /* Initialize with one node pointing to the */
VecU64 bfs_next = VecU64_new();
while (bfs_cur.len > 0) {
do {
U64 pu = VecU64_pop(&bfs_cur);
for (U8 d = 0; d < 26; d++) {
if (fish->nodes.buf[pu].transition[d] != 0) {
U64 u = fish->nodes.buf[pu].transition[d];
U64 u_suf_link = pu == 0 ? 0 : fish->nodes.buf[fish->nodes.buf[pu].suf_link].transition[d];
fish->nodes.buf[u].suf_link = u_suf_link;
if (fish->nodes.buf[u_suf_link].class_ref != -1) {
fish->nodes.buf[u].ans_up_link = u_suf_link;
} else {
fish->nodes.buf[u].ans_up_link = fish->nodes.buf[u_suf_link].ans_up_link;
}
// fish->nodes.buf[pu].transition[d] = u;
VecU64_append(&bfs_next, u);
} else if (pu == 0) {
fish->nodes.buf[pu].transition[d] = 0;
} else {
fish->nodes.buf[pu].transition[d] = fish->nodes.buf[fish->nodes.buf[pu].suf_link].transition[d];
}
}
} while (bfs_cur.len > 0);
VecU64 t = bfs_cur;
bfs_cur = bfs_next;
bfs_next = t;
}
VecU64_drop(bfs_cur);
VecU64_drop(bfs_next);
}
void Fish_drop(Fish self){
VecS64_drop(self.next_same_ref_on_strings);
VecI_FishNode_drop(self.nodes);
}
int main() {
// #ifndef RUNNING_HERE
freopen("inputik.txt", "r", stdin);
freopen("outputik.txt", "w", stdout);
// #endif
VecU8 T = stdin_read_VecU8_nospace();
U64 N = stdin_read_U64_nofail();
VecVecU8 S = VecVecU8_new_of_size(N);
for (size_t i = 0; i < N; i++) {
VecU8 s = stdin_read_VecU8_nospace();
assert(S.buf[i].buf == NULL);
S.buf[i] = s;
}
Fish fish = incomplete_Fish_from_VecU8(VecVecU8_to_span(&S));
// Fish_debug_print(&fish);
complete_Fish(&fish);
VecVecU32 answer = VecVecU32_new_of_size(N);
/* going through T to fill answer */
U64 fish_v = 0;
for (size_t i = 0;; i++) {
int VIBE_CHECK = 0; // Can be safely removed
U64 CUR = fish_v;
while (true) {
S64 j_in_class = fish.nodes.buf[CUR].class_ref;
if (j_in_class == -1) // Can be safely removed
VIBE_CHECK++; // Can be safely removed
while (j_in_class != -1) {
assert(j_in_class < (S64)N);
size_t slen = S.buf[j_in_class].len;
assert(slen <= i);
VecU32_append(&answer.buf[j_in_class], (U32)(i - slen));
j_in_class = fish.next_same_ref_on_strings.buf[j_in_class];
}
/* We give a root a chance to execute, yet this is where we stop */
if (CUR == 0)
break;
CUR = fish.nodes.buf[CUR].ans_up_link;
}
if (VIBE_CHECK > 2) // Can be safely removed
abort(); // Can be safely removed
if (i == T.len)
break;
U8 ch = T.buf[i];
assert('a' <= ch && ch <= 'z');
U8 d = ch - 'a';
assert(d < 26);
fish_v = fish.nodes.buf[fish_v].transition[d];
}
for (size_t i = 0; i < N; i++) {
printf("%lu", answer.buf[i].len);
for (size_t e = 0; e < answer.buf[i].len; e++) {
printf(" %u", answer.buf[i].buf[e] + 1);
}
printf("\n");
}
VecVecU8_drop(S);
VecVecU32_drop(answer);
Fish_drop(fish);
VecU8_drop(T);
return 0;
}

View File

@ -1,287 +0,0 @@
/* __You get millions of volts__ */
#include "../../../../gen/l1/VecAndSpan_U8.h"
#include "../../../../gen/l1/VecAndSpan_VecU8.h"
#include "../../../../gen/l1/VecAndSpan_S64.h"
#include "../../../../gen/l1/VecAndSpan_U64.h"
#include "../../../l1_5/core/input_olproga.h"
typedef struct {
U64 suf_link;
U64 ans_up_link;
U64 transition[26];
S64 class_ref;
} I_FishNode;
I_FishNode I_FishNode_new(){
/* C++ is fucking lame*/
return (I_FishNode){.suf_link = 0, .ans_up_link = 0, .transition = {0}, .class_ref = -1};
// return (I_FishNode){.class_ref = -1};
}
#include "../../../../gen/l1/eve/r_alg/VecI_FishNode.h"
typedef struct {
VecS64 next_same_ref_on_strings;
VecI_FishNode nodes;
} Fish;
Fish incomplete_Fish_from_VecU8(SpanVecU8 S){
VecS64 next_same_ref_on_strings = VecS64_new_filled(S.len, -1);
VecI_FishNode nodes = VecI_FishNode_new_reserved(1000001);
VecI_FishNode_append(&nodes, I_FishNode_new());
assert(nodes.buf[0].suf_link == 0 && nodes.buf[0].ans_up_link == 0 && nodes.buf[0].transition[0] == 0);
for (size_t j = 0; j < S.len; j++) {
SpanU8 str = VecU8_to_span(&S.data[j]);
U64 cur = 0; /* cur trie node */
for (size_t i = 0; i < str.len; i++) {
U8 ch = str.data[i];
assert('a' <= ch && ch <= 'z');
U8 d = ch - 'a';
assert(d < 26);
assert(cur < nodes.len);
if (nodes.buf[cur].transition[d] == 0) {
U64 nid = nodes.len;
VecI_FishNode_append(&nodes, I_FishNode_new());
nodes.buf[cur].transition[d] = nid;
}
assert(nodes.buf[cur].transition[d] < nodes.len);
assert(nodes.buf[cur].transition[d] != 0);
cur = nodes.buf[cur].transition[d];
}
if (nodes.buf[cur].class_ref != -1) {
assert(next_same_ref_on_strings.buf[j] == -1);
next_same_ref_on_strings.buf[j] = nodes.buf[cur].class_ref;
}
nodes.buf[cur].class_ref = (S64)j;
}
return (Fish){.next_same_ref_on_strings=next_same_ref_on_strings, .nodes=nodes};
}
/* Debug function */
void Fish_debug_print(const Fish* self){
printf("next_same_ref_on_strings:\n");
for (size_t i = 0; i < self->next_same_ref_on_strings.len; i++)
printf("%3ld ", self->next_same_ref_on_strings.buf[i]);
printf("\n");
size_t nc = self->nodes.len;
for (size_t i = 0; i < nc; i++)
printf("=== ");
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("%3ld ", self->nodes.buf[i].class_ref);
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("--- ");
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("%3lu ", self->nodes.buf[i].suf_link);
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("--- ");
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("%3lu ", self->nodes.buf[i].ans_up_link);
printf("\n");
for (size_t i = 0; i < nc; i++)
printf("--- ");
printf("\n");
for (U8 d = 0; d < 26; d++) {
for (size_t i = 0; i < nc; i++) {
printf("%3lu ", self->nodes.buf[i].transition[d]);
}
printf("\n");
}
}
void complete_Fish(Fish* fish){
/* trie unpacked */
size_t nc = fish->nodes.len;
assert(nc >= 1);
/* We first, fields suf_link, ans_up_link are filled with garbage */
// Except for root. Root is already almost initialized
assert(fish->nodes.buf[0].suf_link == 0 && fish->nodes.buf[0].ans_up_link == 0);
// Some transitions are already complete. Those that contain 0 are yet to be filled
// transitions to 0 can't occur naturally in Trie. (Incomplete Fish = Trie)
VecU64 bfs_cur = VecU64_new_zeroinit(1); /* Initialize with one node pointing to the */
VecU64 bfs_next = VecU64_new();
while (bfs_cur.len > 0) {
do {
U64 pu = VecU64_pop(&bfs_cur);
for (U8 d = 0; d < 26; d++) {
if (fish->nodes.buf[pu].transition[d] != 0) {
U64 u = fish->nodes.buf[pu].transition[d];
U64 u_suf_link = pu == 0 ? 0 : fish->nodes.buf[fish->nodes.buf[pu].suf_link].transition[d];
fish->nodes.buf[u].suf_link = u_suf_link;
if (fish->nodes.buf[u_suf_link].class_ref != -1) {
fish->nodes.buf[u].ans_up_link = u_suf_link;
} else {
fish->nodes.buf[u].ans_up_link = fish->nodes.buf[u_suf_link].ans_up_link;
}
// fish->nodes.buf[pu].transition[d] = u;
VecU64_append(&bfs_next, u);
} else if (pu == 0) {
fish->nodes.buf[pu].transition[d] = 0;
} else {
fish->nodes.buf[pu].transition[d] = fish->nodes.buf[fish->nodes.buf[pu].suf_link].transition[d];
}
}
} while (bfs_cur.len > 0);
VecU64 t = bfs_cur;
bfs_cur = bfs_next;
bfs_next = t;
}
VecU64_drop(bfs_cur);
VecU64_drop(bfs_next);
}
void Fish_drop(Fish self){
VecS64_drop(self.next_same_ref_on_strings);
VecI_FishNode_drop(self.nodes);
}
typedef struct {
U64 trans[26];
} J_AlphaVertex;
#include "../../../../gen/l1/eve/r_alg/VecJ_AlphaVertex.h"
typedef struct{
size_t only_trash_state;
size_t start;
VecJ_AlphaVertex states;
} AntiGraph;
void AntiGraph_drop(AntiGraph self){
VecJ_AlphaVertex_drop(self.states);
}
U64 Fish_anti_automaton_dfs(U64 fv, VecS64* map, VecJ_AlphaVertex* graph, const VecI_FishNode* fish){
assert(fv < map->len);
assert(fv < fish->len);
/* Priority number 1: check if it is terminal */
if (fish->buf[fv].class_ref != -1 || fish->buf[fish->buf[fv].ans_up_link].class_ref != -1)
return 0; // Trash vertex
if (map->buf[fv] == -1) {
size_t mid = graph->len;
map->buf[fv] = (S64)mid;
/* Right now it is filled with trash. The important point is that it marked as visited */
VecJ_AlphaVertex_append(graph, (J_AlphaVertex){0});
for (U8 d = 0; d < 26; d++) {
U64 nnon = Fish_anti_automaton_dfs(fish->buf[fv].transition[d], map, graph, fish);
graph->buf[mid].trans[d] = nnon;
}
}
return map->buf[fv];
}
AntiGraph Fish_anti_automaton(Fish fish){
size_t nc = fish.nodes.len;
assert(nc > 0);
/* starting with just trash vertex, it ppints to inself, zalooping on itself */
VecJ_AlphaVertex graph = VecJ_AlphaVertex_new_zeroinit(1);
VecS64 map = VecS64_new_filled(nc, -1);
U64 start = Fish_anti_automaton_dfs(0, &map, &graph, &fish.nodes);
Fish_drop(fish);
VecS64_drop(map);
return (AntiGraph){.only_trash_state = 0, .start = start, .states = graph};
}
#define MOD (1000000007)
NODISCARD VecU64 mat_mul(uint32_t N, const VecU64* A, const VecU64* B){
assert(A->len == N * N && B->len == N * N);
VecU64 C = VecU64_new_zeroinit(N * N);
for (size_t y = 0; y < N; y++) {
for (size_t x = 0; x < N; x++) {
size_t s = 0;
for (size_t k = 0; k < N; k++) {
s = (s + (A->buf[y * N + k] * B->buf[k * N + x]) % MOD) % MOD;
}
C.buf[y * N + x] = s;
}
}
return C;
}
NODISCARD VecU64 pow_matrix(uint32_t N, const VecU64* A, uint64_t B){
if (B == 0) {
VecU64 E = VecU64_new_zeroinit(N * N);
for (size_t k = 0; k < N; k++)
E.buf[N * k + k] = 1;
return E;
}
if (B == 1)
return VecU64_clone(A);
uint64_t b = B / 2;
VecU64 e = pow_matrix(N, A, b);
assert(e.len == N * N);
VecU64 E = mat_mul(N, &e, &e);
VecU64_drop(e); // e is no more
if (B % 2 == 0)
return E;
VecU64 F = mat_mul(N, &E, A);
VecU64_drop(E);
return F;
}
void VecU64_debug_print_cool_matrix(size_t N, const VecU64* matrix){
assert(matrix->len == N * N);
for (size_t y = 0; y < N; y++) {
for (size_t x = 0; x < N; x++)
printf(" %2lu", matrix->buf[y * N + x]);
printf("\n");
}
}
int main(){
U64 K = stdin_read_U64_nofail();
U64 m = stdin_read_U64_nofail();
VecVecU8 S = VecVecU8_new_of_size(m);
for (size_t i = 0; i < m; i++) {
U64 sn = stdin_read_U64_nofail();
if (sn == 0)
abort();
assert(S.buf[i].buf == NULL);
S.buf[i] = stdin_read_VecU8_nospace();
// assert(S.buf[i].len == sn);
}
// I_Trie_debug_print(&trie);
Fish fish = incomplete_Fish_from_VecU8(VecVecU8_to_span(&S));
complete_Fish(&fish);
// Fish_debug_print(&fish);
AntiGraph antigraph = Fish_anti_automaton(fish);
size_t N = antigraph.states.len;
assert(1 < N);
assert(0 == antigraph.only_trash_state);
VecU64 graph_matrix = VecU64_new_zeroinit(N * N);
for (size_t v = 0; v < N; v++) {
for (U8 d = 0; d < 26; d++) {
size_t t = antigraph.states.buf[v].trans[d];
assert(t < N);
graph_matrix.buf[t * N + v]++;
}
}
// VecU64_debug_print_cool_matrix(N, &graph_matrix);
VecU64 K_graph_matrix = pow_matrix(N, &graph_matrix, K);
U64 K_paths = 0;
for (size_t endpoint = 1; endpoint < N; endpoint++) {
K_paths = (K_paths + K_graph_matrix.buf[endpoint * N + antigraph.start]) % MOD;
}
printf("%lu\n", K_paths);
VecU64_drop(graph_matrix);
VecU64_drop(K_graph_matrix);
AntiGraph_drop(antigraph);
VecVecU8_drop(S);
}