Cod sursa(job #1422860)

Utilizator Breje_RaulRaul Breje Breje_Raul Data 20 aprilie 2015 00:00:48
Problema Potrivirea sirurilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 1e6+5;
const int P = 73;

const int MODULO[] = {100007, 100021};
const int MODSIZE = 2;

ifstream f("strmatch.in");
ofstream g("strmatch.out");

string pattern, text;
vector< vector<int> > hashValuesText, hashValuesPattern;
vector< vector<int> > put;

vector< vector<int> >getHashValues(string s){
    vector< vector<int> > hashValues;
    vector<int> currentHash;
    for(int i=0; i<MODSIZE; ++i){
        currentHash.push_back(0);
    }

    for(int i=0; i<s.size(); ++i){
        vector<int> v;
        for(int j=0; j<MODSIZE; ++j){
            int currentHashValue = (currentHash[j] * P + s[i]) % MODULO[j];
            currentHash[j] = currentHashValue;
            v.push_back(currentHash[j]);
        }
        hashValues.push_back(v);
        /*
        for(int j=0; j<v.size(); ++j){
            cout << v[j] << " ";
        }cout << "\nmuie";*/
    }

    return hashValues;
}

int getHashTextSequence(int x, int y, int tip){
    int dreapta = hashValuesText[y][tip];
    if (x == 0){
        return dreapta;
    }
    int stanga = hashValuesText[x-1][tip];
    stanga = (1LL*stanga*put[y-x+1][tip]) % MODULO[tip];
    return ( (dreapta - stanga + MODULO[tip]) % MODULO[tip]);
}

void solve(){
    vector<int> v2;
    for(int i=0; i<MODSIZE; ++i){
        v2.push_back(1);
    }
    put.push_back(v2);
    for(int i=1; i<text.size(); ++i){
        vector<int> v;
        for(int j=0; j<MODSIZE; ++j){
            int prev = (put[i-1][j] * P) % MODULO[j];
            v.push_back( prev );
        }
        put.push_back(v);
        /*
        cout << i << " " << "umreaza\n";
        for(int j=0; j<v.size(); ++j) cout << put[i][j] << " ";cout << "\n";*/
    }

    vector<int> ans;
    for(int i=pattern.size()-1; i<text.size(); ++i){
        int same = 1;
        for(int j=0; j<MODSIZE; ++j){
            if ( getHashTextSequence(i-pattern.size()+1, i, j) != hashValuesPattern[pattern.size()-1][j] ){
                same = 0;
                break;
            }
            /*
            if (i == 8 || i == 2){
                cout << "aicic : " << getHashTextSequence(i-pattern.size()+1, i, j) << " " << hashValuesPattern[pattern.size()-1][j] << "\n";
            }*/
        }
        if (same){
            ans.push_back(i-pattern.size()+1);
        }
    }
    g << min((int)ans.size(), 1000) << "\n";
    for(int i=0; i<min((int)ans.size(), 1000); ++i){
        g << ans[i] << " ";
    }
}

int main(){
    getline(f, pattern);
    getline(f, text);
    //cout << pattern << "\n";
    hashValuesPattern = getHashValues(pattern);
/*
    for(int i=0; i<MODSIZE; ++i){
        for(int j=0; j<pattern.size(); ++j){
            cout << hashValuesPattern[j][i] << " ";
        }cout << "\n";
    }*/
    hashValuesText = getHashValues(text);

    solve();

    return 0;
}