Cod sursa(job #113309)

Utilizator cos_minBondane Cosmin cos_min Data 9 decembrie 2007 17:31:24
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 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
#define SizeL1(i) L1[i][0]
#define SizeL2(i) L2[i][0]

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

// hashing sintax

ull L1[modulo][5], L2[modulo][5];

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++ ) L1[i][0] = L2[i][0] = 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; 
          int j = 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);
    
    for ( int i = 0; i <= N-M; i++ )
    {
        if ( i == 0 )
        {
             T = 0;
             for ( int j = i; j < i+M; j++ )
             {
                  T += ((int)(Cuvant[j]-96))*H, H /= 3;
                  poz = j;
             }
        }
        else
        {
            poz += 1;
            
            T -= H1*((int)(Cuvant[i-1]-96));
            T *= 3;
            T += (int)(Cuvant[poz]-96);
        }
        
        Total += Search(T, T%modulo);
    }
    
    printf("%d", Total);
       
}

bool Search(ull X, int NR)
{
     bool ok = 0;
     int j = 0;
     
     while ( j < Maxim(SizeL1(NR),SizeL2(NR)) && !ok )
     {
           if ( j <= SizeL1(NR) && L1[NR][j] == X ) return 1;
           if ( j <= SizeL2(NR) && L2[NR][j] == X ) return 1;
           j++;
     }
     
     return 0;
}

void Add(ull X, int NR)
{
     if ( SizeL1(NR) < SizeL2(NR) ) L1[NR][0] += 1,  L1[NR][SizeL1(NR)] = X;
     else                           L2[NR][0] += 1,  L2[NR][SizeL2(NR)] = X;
}