Cod sursa(job #655602)

Utilizator nautilusCohal Alexandru nautilus Data 2 ianuarie 2012 23:29:55
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 kb
#include<fstream>
#include<algorithm>
using namespace std;
#define SMAX 10000010
#define CMAX 25
#define PUTERE 101
#define PRIM1 100003
#define PRIM2 100019

typedef struct hashh
{
 int unu,doi,ok;
} hashh;

int n;
hashh hashs[SMAX];

char s[SMAX];
int lungs,lungc,nrcuvpos;
int hashcunu,hashcdoi,copie;
int pozinceput,pozsfarsit,pozitiicandidat;

bool comp (hashh a, hashh b)
{
 if (a.unu = b.unu)
	return a.doi < b.doi; else
	return a.unu < b.unu;
}

void preprocesare()
{
 int i;
 int puteremax1=1,puteremax2=1;
 for (i=0; i<lungc; ++i)
	{
	 hashs[0].unu = (hashs[0].unu * PUTERE + s[i]) % PRIM1;
	 hashs[0].doi = (hashs[0].doi * PUTERE + s[i]) % PRIM2;
	 if (i > 0)
		{
		 puteremax1 = (puteremax1 * PUTERE) % PRIM1;
		 puteremax2 = (puteremax2 * PUTERE) % PRIM2;
		}
	}
 for (i=1; i<=lungs - lungc; ++i)
	{
	 hashs[i].unu = ((hashs[i-1].unu - (s[i-1] * puteremax1) % PRIM1 + PRIM1) * PUTERE + s[i + lungc - 1]) % PRIM1;
	 hashs[i].doi = ((hashs[i-1].doi - (s[i-1] * puteremax2) % PRIM2 + PRIM2) * PUTERE + s[i + lungc - 1]) % PRIM2;
	}
 nrcuvpos = lungs - lungc + 1;
 sort(hashs, hashs+nrcuvpos, comp);
}

void cauta_inceput(int st, int dr)
{
 int mijl = (st + dr) / 2;

 if (st <= dr)
	{
	 if (hashs[mijl].unu == hashcunu && hashs[mijl].doi == hashcdoi)
		 if (hashs[mijl].ok == 0)
			{
			 pozinceput = mijl;
			 cauta_inceput(st, mijl-1);
			} else
			{
			 copie = 1;
			 return;
			} else
		 if ((hashs[mijl].unu == hashcunu && hashs[mijl].doi > hashcdoi) || hashs[mijl].unu > hashcunu)
			 cauta_inceput(st, mijl-1); else
			 cauta_inceput(mijl+1, dr);
	}
}

void cauta_sfarsit(int st, int dr)
{
 int mijl = (st + dr) / 2;

 if (st <= dr)
	{
	 if (hashs[mijl].unu == hashcunu && hashs[mijl].doi == hashcdoi)
		 {
		 pozsfarsit = mijl;
		 cauta_sfarsit(mijl+1, dr);
		 } else
		 if ((hashs[mijl].unu == hashcunu && hashs[mijl].doi > hashcdoi) || hashs[mijl].unu > hashcunu)
			 cauta_sfarsit(st, mijl-1); else
			 cauta_sfarsit(mijl+1, dr);
	}
}

void read()
{
 int i;
 char c[CMAX];
 
 ifstream fin("abc2.in");

 fin.get(s, SMAX); fin.get();
 lungs = (int)strlen(s);

 while ( !fin.eof() )
	{
	 fin.get(c, CMAX); fin.get();
	 if (lungc == 0)
		{
		 lungc = (int)strlen(c);
		 preprocesare();
		}

	 hashcunu = hashcdoi = 0;
	 for (i=0; i<(int)strlen(c); ++i)
		{
		 hashcunu = (hashcunu * PUTERE + c[i]) % PRIM1;
		 hashcdoi = (hashcdoi * PUTERE + c[i]) % PRIM2;
		}

	 pozinceput = pozsfarsit = -1; copie = 0;
	 cauta_inceput(0, nrcuvpos);
	 if (copie == 0 && pozinceput != -1)
		cauta_sfarsit(0,nrcuvpos);

	 if (pozinceput != -1)
		{
		 pozitiicandidat += pozsfarsit - pozinceput + 1;
		 for (i=pozinceput; i<=pozsfarsit; ++i)
			 hashs[i].ok = 1;
		}
	}
}

void write()
{
 ofstream fout("abc2.out");
 fout<<pozitiicandidat<<'\n';
 fout.close();
}

int main()
{
 read();
 write();

 return 0;
}