Cod sursa(job #1971102)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 19 aprilie 2017 20:18:48
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <stdint.h>
#include <fstream>
#include <string.h>
#define nmax 10000001
#define nrmaxcuv 50001
#define mmax 21
#define mod 666013
using namespace std;
fstream f1("abc2.in", ios::in);
fstream f2("abc2.out", ios::out);
char sir[nmax], cuv[mmax];
uint32_t n, nrt, t[nrmaxcuv], rez;
int16_t m;
const int16_t d=3;
uint32_t ct;///=d^(m-1)
uint32_t hash_c()
{
    int16_t i;
    uint32_t h=0;
    for(i=0; i<m; i++)
        {
            h=h*d+(cuv[i]-'a');
        }
    return h%mod;
}
uint32_t hash_s()
{
    int16_t i;
    uint32_t h=0;
    for(i=0; i<m; i++)
        {
            h=h*d+(sir[i]-'a');
        }
    return  h%mod;
}
void putere()
{
    int16_t i;
    ct=1;
    for(i=1; i<m; i++)
        ct*=d;

     ct%=mod;
}
void adauga(uint32_t st, uint32_t dr, uint32_t val)
{
    if(st<=dr)
    {
        uint32_t mijl=(st+dr)/2;
        if(val==t[mijl]) ;
        else if(val< t[mijl]) adauga(st, mijl-1, val);
        else adauga(mijl+1, dr, val);
    }
    else
    {
        ///adaugi in locul poz st valoarea val
        uint32_t i;
        for(i=nrt; i>=st; i--)
            t[i+1]=t[i];
        t[st]=val;
        nrt++;
    }
}
int16_t find_c(uint32_t st, uint32_t dr, uint32_t val)
{
    if(st<=dr)
    {
        uint32_t mijl=(st+dr)/2;
        if(t[mijl]==val) return 1;
        else if(t[mijl]<val) return find_c(mijl+1, dr, val);
        else return find_c(st, mijl-1, val);
    }
    else return 0;
}
int main()
{
    uint32_t val, i;
    f1>>sir; n=strlen(sir);
    f1>>cuv; m=strlen(cuv);
    do
    {
        val=hash_c();
        adauga(1, nrt, val);///adaugi cu cautare biara val cuv curent daca nu exista in t
    }while(f1>>cuv);

    val=hash_s();
    rez+=find_c(1, nrt, val);///cauti nr coresp primei secv in vectorul t de dimensiune nr(cautare binara)
    putere();///calc ct, care te ajuta sa faci trecerea intre secv textului lung

    for(i=1; i<=n-m; i++)
    {
        ///treci la urmatoarea secv modificand hashul pt val
        val= val- ct*(sir[i-1]-'a');
        val= (val*d+ sir[i+m-1]-'a')%mod;
        rez+=find_c(1, nrt, val);
    }
    f2<<rez;
    return 0;
}