Cod sursa(job #169412)

Utilizator DastasIonescu Vlad Dastas Data 1 aprilie 2008 17:57:07
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

const int maxn = 10000002;
const int maxl = 30;
const int maxc = 50001;

const int mod1 = 1 << 18;//128213;
const int mod2 = 1 << 17;//100021;
const int pp1 = 3;
const int pp2 = 73;

FILE *in = fopen("abc2.in","r"), *out = fopen("abc2.out","w");

char a[maxn];

int n, m;
char c[maxc][maxl];

int h1[mod1] = {0};
int h2[mod2] = {0};

vector<int> l[mod1];

int p1[maxl];
int p2[maxl];

int pow(int a, int b, int mod)
{
    int s = 1;

    for ( int i = 1; i <= b; ++i )
        s *= a,
        s %= mod;

    return s;
}

int j = 1;
void getnr()
{
    int hash1 = 0, hash2 = 0;

    for ( int i = 0; i < n; ++i )
    {
        hash1 = (hash1 + p1[i] * c[j][i]) % mod1;
        hash2 = (hash2 + p2[i] * c[j][i]) % mod2;
    }

    ++h1[ hash1 ];
    ++h2[ hash2 ];

    l[ hash1 ].push_back(j);
}

int check(int what, int from, int to)
{
    char t[maxl];
    for ( int i = from; i <= to; ++i )
        t[i - from] = a[i];
    t[to+1] = '\0';

    for ( int i = 0, N = h1[ what ]; i < N; ++i )
        if ( !strcmp(c[ l[ what ][i] ], t) )
            return 1;

    return 0;
}

int cnt;
int main()
{
    fscanf(in, "%s", a);
    m = strlen(a);

    fscanf(in, "%s", c[1]);
    n = strlen(c[1]);

    for ( int i = 0; i < n; ++i )
        p1[i] = pow(pp1, n - i - 1, mod1),
        p2[i] = pow(pp2, n - i - 1, mod2);

    //for ( int i = 0; i < n; ++i )
    //    printf("%d %d\n", p1[i], p2[i]);

    getnr();
    ++j;

    while ( fscanf(in, "%s", c[j]) == 1 )
        getnr(), ++j;


    int hash1 = 0, hash2 = 0;
    for ( int i = 0; i < n; ++i )
    {
        hash1 = (hash1 + p1[i] * a[i]) % mod1;
        hash2 = (hash2 + p2[i] * a[i]) % mod2;
    }

    if ( h1[ hash1 ] && h2[ hash2 ] )
        if ( check(hash1, 0, n - 1) )
            ++cnt;

    for ( int i = n; i < m; ++i )
    {
        hash1 = ((hash1 - ((a[i - n] * p1[0]) % mod1) + mod1) * pp1 + a[i]) % mod1;
        hash2 = ((hash2 - ((a[i - n] * p2[0]) % mod2) + mod2) * pp2 + a[i]) % mod2;

        if ( h1[ hash1 ] && h2[ hash2 ] )
            if ( check(hash1, i - n + 1, i) )
                ++cnt;
    }

    fprintf(out, "%d\n", cnt);

    return 0;
}