0w1

UVA 10391 - Compound Words ( Hash )

Kind of tried making hashing look reusable.

#include <bits/stdc++.h>
using namespace std;

const int MOD = 1e9 + 7;
vector< int > hmul = { 10007, 10009, 10039, 10061, 10069, 10093, 10103, 10141, 10177 };

template< typename T >
int vtoi( const T &v ){
    return v - 'a' + 1;
}

int get_hash( string s, int k ){
    int res = 0;
    for( int i = 0; i < s.size(); ++i )
        ( res = 1LL * res * hmul[ k ] % MOD + vtoi( s[ i ] ) ) %= MOD;
    return res;
}

int get_hash( string s, int k, int l, int r ){ // [ l, r ]
    int res = 0;
    for( int i = l; i <= r; ++i )
        ( res = 1LL * res * hmul[ k ] % MOD + vtoi( s[ i ] ) ) %= MOD;
    return res;
}

void solve(){
    set< string > ans;
    vector< string > dict;
    vector< set< int > > hvset( hmul.size() );

    string _s;
    while( cin >> _s ){
        dict.push_back( _s );
        for( int k = 0; k < hmul.size(); ++k )
            hvset[ k ].insert( get_hash( _s, k ) );
    }

    for( int i = 0; i < dict.size(); ++i ){
        bool found = false;
        for( int j = 1; j <= dict[ i ].size() - 1; ++j ){
            string l = dict[ i ].substr( 0, j );
            string r = dict[ i ].substr( j, dict[ i ].size() - j );
            // if( l == r ) continue; THIS LED TO MY WA
            bool fail = false;
            for( int k = 0; k < hmul.size(); ++k ){
                int hv1 = get_hash( l, k ); // get_hash( dict[ i ], k, 0, j );
                int hv2 = get_hash( r, k ); // get_hash( dict[ i ], k, j + 1, dict[ i ].size() - 1 );
                if( !hvset[ k ].count( hv1 ) or !hvset[ k ].count( hv2 ) ){
                    fail = true;
                    break;
                }
            }
            if( !fail ){
                found = true;
                break;
            }
        }
        if( found )
            ans.insert( dict[ i ] );
    }

    for( const string &s : ans )
        cout << s << "\n";
}

int main(){
    ios::sync_with_stdio( false );
    solve();
    return 0;
}