Cod sursa(job #2700518)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 27 ianuarie 2021 22:02:11
Problema Abc2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <fstream>
#include <cstring>
#include <cmath>

using namespace std;

//parsare
const int BUFF_SIZE_IN = 4096;
const int BUFF_SIZE_OUT = 50000;

char* in_buff, * out_buff;

int in_pos = BUFF_SIZE_IN - 1, out_pos = BUFF_SIZE_OUT - 1;

FILE* in, * out;

char read_ch() {
    ++in_pos;
    if (in_pos == BUFF_SIZE_IN) {
        in_pos = 0;
        in_buff = new char[BUFF_SIZE_IN]();
        fread(in_buff, 1, BUFF_SIZE_IN, in);
    }
    return in_buff[in_pos];
}

bool read_str(char* str) {
    char ch;
    int len = 0;
    do {
        ch = read_ch();
        str[len++] = ch;
    } while (ch && ch != '\n');
    str[len - 1] = 0;
    if (len == 1)
        return false;
    return true;
}

void flush(int sz) {
    if (!out_buff)
        return;
    fwrite(out_buff, 1, sz, out);
}

void write_ch(char ch) {
    ++out_pos;
    if (out_pos == BUFF_SIZE_OUT) {
        out_pos = 0;
        flush(BUFF_SIZE_OUT);
        out_buff = new char[BUFF_SIZE_OUT]();
    }
    out_buff[out_pos] = ch;
}

void write_int(int n) {
    if (!n)
        return;
    write_int(n / 10);
    write_ch(n % 10 + '0'); 
}

//continuare program
const int N = 1e7;
const int LMAX = 20;
const int MOD = 666019;

char s[N + 1], cuv[LMAX + 1];
int lst[MOD], urm[N + 1], nr = 0, ls, lcuv;
pair<unsigned, int> val[N + 1];

int cauta(unsigned x) {
    int c = x % MOD, p = lst[c];
    while (p && val[p].first != x)
        p = urm[p];
    if (p)
        return p;
    return -1;
}

void adauga(unsigned x) {
    int p = cauta(x), c = x % MOD;
    if (p == -1) {
        val[++nr] = { x, 1 };
        urm[nr] = lst[c];
        lst[c] = nr;
    }
    else
        ++val[p].second;
}

void init_hash() {
    unsigned h = 0;
    for (int i = 0; i < lcuv; ++i)
        h = h * 3 + (s[i] - 'a');
    adauga(h);
    unsigned p3 = pow(3, lcuv - 1);
    for (int i = lcuv; i < ls; ++i) {
        h %= p3;
        h = h * 3 + (s[i] - 'a');
        adauga(h);
    }
}

unsigned hash_cuv() {
    unsigned h = 0;
    for (int i = 0; i < lcuv; ++i)
        h = h * 3 + (cuv[i] - 'a');
    return h;
}

int count(unsigned x) {
    int p = cauta(x);
    if (p != -1) {
        int ret = val[p].second, c = x % MOD;
        swap(val[p], val[lst[c]]);
        lst[c] = urm[lst[c]];
        return ret;
    }
    return 0;
}

int main() {
    in = fopen("abc2.in", "r");
    out = fopen("abc2.out", "w");
    read_str(s), read_str(cuv);
    ls = strlen(s), lcuv = strlen(cuv);
    if (ls < lcuv) {
        write_ch('0');
        flush(out_pos + 1);
        fclose(in);
        fclose(out);
        return 0;
    }
    init_hash();
    unsigned h;
    int rez = 0;
    do {
        h = hash_cuv();
        rez += count(h);
    } while (read_str(cuv));
    write_int(rez);
    flush(out_pos + 1);
    fclose(in);
    fclose(out);
    return 0;
}