Cod sursa(job #113318)

Utilizator cos_minBondane Cosmin cos_min Data 9 decembrie 2007 17:42:42
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 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 long
#define Maxim(a,b) a > b ? a : b

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

// hashing sintax

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

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

//

int main()
{
    int poz, Total=0;
    ull X, H, H1, NR;
    bool ok;
    
    for ( int i = 0; i < modulo; i++ ) Size1[i] = Size2[i] = 0;
    
    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++;
          }
          
          ok = 0; 
          NR = X%modulo;
          
          if ( Search(X,NR) ) continue; // il am deja in hash
          
          Add(X,NR);
    }
    
    ull 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(ull X, int NR)
{
     bool ok = 0;
     int j = 0;
     
     while ( j <= Maxim(Size1[NR],Size2[NR]) && !ok )
     {
           if ( j <= Size1[NR] && L1[NR][j] == X ) return 1;
           if ( j <= Size2[NR] && L2[NR][j] == X ) return 1;
           j++;
     }
     
     return 0;
}

void Add(ull 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;
}