제출 #529588

#제출 시각아이디문제언어결과실행 시간메모리
529588c28dnv9q3Crossing (JOI21_crossing)C++17
100 / 100
2424 ms28068 KiB
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#pragma GCC optimize "O3"

#define _strfy(s) #s
#define strfy(s) _strfy(s)

#define ALPHABET "JOI"

#define MAX_N 200000
int seq_len;
char seqA[MAX_N+1], seqB[MAX_N+1], seqC[MAX_N+1];
char seqAB[MAX_N+1], seqBC[MAX_N+1], seqAC[MAX_N+1];
char seqABC[MAX_N+1], seqBCA[MAX_N+1], seqACB[MAX_N+1];
char seqT[MAX_N+1];

#define MAX_Q 200000
int num_mods;
struct mod {
    int left, right;
    char chr;
} mods[MAX_Q];
bool posbl[MAX_Q+1];

static inline void validate(const char *seq) {
    assert(strlen(seq) == seq_len);
    for(; *seq != 0; seq++) assert(*seq == ALPHABET[0] || *seq == ALPHABET[1] || *seq == ALPHABET[2]);
}

static inline void cross(const char *seq1, const char *seq2, char *seqO) {
    for(int i = 0; i < seq_len; i++) {
        if(seq1[i] == seq2[i]) seqO[i] = seq1[i];
        else if(seq1[i] == ALPHABET[1] && seq2[i] == ALPHABET[2]) seqO[i] = ALPHABET[0];
        else if(seq1[i] == ALPHABET[2] && seq2[i] == ALPHABET[1]) seqO[i] = ALPHABET[0];
        else if(seq1[i] == ALPHABET[0] && seq2[i] == ALPHABET[2]) seqO[i] = ALPHABET[1];
        else if(seq1[i] == ALPHABET[2] && seq2[i] == ALPHABET[0]) seqO[i] = ALPHABET[1];
        else if(seq1[i] == ALPHABET[0] && seq2[i] == ALPHABET[1]) seqO[i] = ALPHABET[2];
        else if(seq1[i] == ALPHABET[1] && seq2[i] == ALPHABET[0]) seqO[i] = ALPHABET[2];
        else assert(false);
    }
}

struct node {
    struct node *lchild, *rchild;
    int left, right;

    int lazy_c;

    int numA, numB, numC;
    int numM; //numMatch
} nodes[2*MAX_N], *next_node;

struct node *create_tree(const char *seq, int l = -1, int r = -1) {
    if(l < 0 && r < 0) {
        next_node = nodes;
        l = 0;
        r = seq_len;
    }

    assert(0 <= l && l < r && r <= seq_len);
    assert(next_node < nodes + 2*MAX_N);

    struct node *node = next_node++;
    node->left = l;
    node->right = r;
    node->lazy_c = -1;

    if(l == r - 1) {
        node->lchild = NULL;
        node->rchild = NULL;
        node->numA = (seq[l] == ALPHABET[0]) ? 1 : 0;
        node->numB = (seq[l] == ALPHABET[1]) ? 1 : 0;
        node->numC = (seq[l] == ALPHABET[2]) ? 1 : 0;
        node->numM = (seq[l] == seqT[l]) ? 1 : 0;
    } else {
        int m = l + (r - l) / 2;
        node->lchild = create_tree(seq, l, m);
        node->rchild = create_tree(seq, m, r);
        node->numA = node->lchild->numA + node->rchild->numA;
        node->numB = node->lchild->numB + node->rchild->numB;
        node->numC = node->lchild->numC + node->rchild->numC;
        node->numM = node->lchild->numM + node->rchild->numM;
    }

    return node;
}

void update_lazy(struct node *node) {
    if(node->lazy_c < 0) return;

    switch(node->lazy_c) {
        case(ALPHABET[0]): { node->numM = node->numA; } break;
        case(ALPHABET[1]): { node->numM = node->numB; } break;
        case(ALPHABET[2]): { node->numM = node->numC; } break;
        default: assert(false);
    }

    if(node->lchild != NULL) node->lchild->lazy_c = node->lazy_c;
    if(node->rchild != NULL) node->rchild->lazy_c = node->lazy_c;

    node->lazy_c = -1;
}

void update_tree(struct node *node, int l, int r, char c) {
    update_lazy(node);

    assert(0 <= l && l < r && r <= seq_len);
    assert(0 <= node->left && node->left < node->right && node->right <= seq_len);
    
    if(r <= node->left || node->right <= l) return;

    if(l <= node->left && node->right <= r) {
        node->lazy_c = c;
        update_lazy(node);
        return;
    }

    assert(node->lchild != NULL && node->rchild != NULL);
    update_tree(node->lchild, l, r, c);
    update_tree(node->rchild, l, r, c);
    node->numM = node->lchild->numM + node->rchild->numM;
}

void check_seq(const char *seq) {
    struct node *tree = create_tree(seq);

    for(int m = -1; m < num_mods; m++) {
        if(m >= 0) update_tree(tree, mods[m].left, mods[m].right, mods[m].chr);

        assert(0 <= tree->numM && tree->numM <= seq_len);
        posbl[m+1] = posbl[m+1] || tree->numM == seq_len;
    }
}

int main() {
    assert(scanf("%d", &seq_len) == 1);
    assert(1 <= seq_len && seq_len <= MAX_N);

    assert(scanf("%" strfy(MAX_N) "s", seqA) == 1);
    validate(seqA);
    assert(scanf("%" strfy(MAX_N) "s", seqB) == 1);
    validate(seqB);
    assert(scanf("%" strfy(MAX_N) "s", seqC) == 1);
    validate(seqC);

    cross(seqA, seqB, seqAB);
    cross(seqB, seqC, seqBC);
    cross(seqA, seqC, seqAC);

    cross(seqAB, seqC, seqABC);
    cross(seqBC, seqA, seqBCA);
    cross(seqAC, seqB, seqACB);

    assert(scanf("%d", &num_mods) == 1);
    assert(1 <= num_mods && num_mods <= MAX_Q);

    assert(scanf("%" strfy(MAX_N) "s", seqT) == 1);
    validate(seqT);

    posbl[0] = false;
    for(int m = 0; m < num_mods; m++) {
        int l, r;
        char c;
        assert(scanf("%d %d %c", &l, &r, &c) == 3);
        assert(1 <= l && l <= r && r <= seq_len);
        assert(c == ALPHABET[0] || c == ALPHABET[1] || c == ALPHABET[2]);

        mods[m].left = l-1;
        mods[m].right = r;
        mods[m].chr = c;
        posbl[m+1] = false;
    }

    check_seq(seqA);
    check_seq(seqB);
    check_seq(seqC);

    check_seq(seqAB);
    check_seq(seqBC);
    check_seq(seqAC);

    check_seq(seqABC);
    check_seq(seqBCA);
    check_seq(seqACB);

    for(int m = 0; m <= num_mods; m++) {
        if(posbl[m]) puts("Yes");
        else puts("No");
    }

    return EXIT_SUCCESS;
}

컴파일 시 표준 에러 (stderr) 메시지

In file included from Main.cpp:4:
Main.cpp: In function 'void validate(const char*)':
Main.cpp:29:24: warning: comparison of integer expressions of different signedness: 'size_t' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   29 |     assert(strlen(seq) == seq_len);
      |            ~~~~~~~~~~~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...