Cod sursa(job #113332)

Utilizator cos_minBondane Cosmin cos_min Data 9 decembrie 2007 18:03:02
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.8 kb
// 7 teste Ok + 3 tle = 0 pcte
// V2 : 2 tabele de hashing

#include <stdio.h>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <math.h>
using namespace std;

#define in "abc2.in"
#define out "abc2.out"
#define dim 10000003
#define modulo 666013
#define ull unsigned long
#define Maxim(a,b) a > b ? a : b

int N=0,M;
int S[23];
char Cuvant[dim], linie[23];

vector<unsigned int> V;

// hashing sintax

unsigned int L1[modulo][7], L2[modulo][7];
int Size1[modulo], Size2[modulo];

void Add(unsigned int,int);
bool Search(unsigned int,int);

//

int main()
{
    int poz, Total=0;
    unsigned int X, H, H1, NR;
    bool ok;
    
    for ( int i = 0; i < modulo; i++ ) Size1[i] = Size2[i] = -1;
    
    FILE *fin = fopen(in,"r");
    freopen(out,"w",stdout);
    
    fgets(Cuvant,dim-1,fin);
    
    while ( Cuvant[N] >= 'a' && Cuvant[N] <= 'c' ) N++;
    
    while ( fgets(linie,22,fin) ) 
    {
          poz = 0;
          while ( linie[poz] >= 'a' && linie[poz] <= 'c' ) poz++;
          
          M = poz;
          H = (int)(pow(3,poz-1)), X = 0, poz = 0;
          
          while ( H )
          {
                X += ((int)linie[poz]-96)*H;
                H /= 3, poz++;
          }
          
          V.push_back(X);
    }
    
    sort(V.begin(),V.end());
    
    for ( int i = 0; i < V.size(); i++ )
    {
        NR = V[i] % modulo;
        if ( Search(V[i],NR) ) continue;
        
        Add(V[i],NR);
    }
    
    unsigned int T;
    H = H1 = (int)pow(3,M-1);
    
    T = 0;
    
    for ( int j = 0; j < M; j++ )
    {
        T += ((int)(Cuvant[j]-96))*H, H /= 3;
        poz = j;
    }
    
    for ( int i = 0; i <= N-M; i++ )
    {
        Total += Search(T, T%modulo);
        
        poz += 1;
            
        T -= H1*((int)(Cuvant[i]-96)); 
        T *= 3;
        T += (int)(Cuvant[poz]-96);
    }
    
    printf("%d", Total);
       
}

bool Search(unsigned int X, int NR)
{
     bool ok = 0;
     int C = Maxim(Size1[NR],Size2[NR]), j=0;
     
     while ( j <= C && !ok )
     {
           ok = 0;
           
           if ( j <= Size1[NR] ) 
           {
                if ( L1[NR][j] == X ) return 1;
                else if ( L1[NR][j] < X ) ok = 1;
           }
             
           if ( j <= Size2[NR] ) 
           {
                if( L2[NR][j] == X ) return 1;
                else if ( L2[NR][j] < X ) ok = 1;
           }
           
           if ( ok == 0 ) return 0;
           
           j++;
     }
     
     return 0;
}

void Add(unsigned int X, int NR)
{
     if ( Size1[NR] < Size2[NR] ) Size1[NR] += 1,  L1[NR][Size1[NR]] = X;
     else                         Size2[NR] += 1,  L2[NR][Size2[NR]] = X;
}