Cod sursa(job #2207645)

Utilizator dragomir_ioanDragomir Ioan dragomir_ioan Data 26 mai 2018 10:58:31
Problema Potrivirea sirurilor Scor 38
Compilator c Status done
Runda Arhiva educationala Marime 1.66 kb

#include <stdio.h>
#include <string.h>

#define M1 666013
#define M2 1000003

char mare[2000001], mic[2000001];

int rezultate[1000], cate;

inline long long lookup(char c) {
	if(c <= '9') return c - '0';
	if(c <= 'Z') return c - 'A' + 10;
	return c - 'a' + 36;
}

int main() {
	FILE *fin = fopen("strmatch.in", "r");

	fgets(mic, 2000001, fin);
	fgets(mare, 2000001, fin);

	mic[strcspn(mic, "\r\n")] = 0;
	mare[strcspn(mare, "\r\n")] = 0;

	int l_mic = strlen(mic);
	int l_mare = strlen(mare);
	fclose(fin);

	long long hash1 = 0, hash2 = 0,		// hashurile bucatii mici
		puterea1 = 1, puterea2 = 1,		// 62 la puterea l_mic-1
		rolling1 = 0, rolling2 = 0;		// hashurile secventelor din aia mare

	for(int i=0; i<l_mic; i++) {
		hash1 = (hash1 * 62 + lookup(mic[i])) % M1;
		hash2 = (hash2 * 62 + lookup(mic[i])) % M2;

		rolling1 = (rolling1 * 62 + lookup(mare[i])) % M1;
		rolling2 = (rolling2 * 62 + lookup(mare[i])) % M2;

		if(i != 0) {	// sa sarim _un singur_ pas
			puterea1 = puterea1 * 62 % M1;
			puterea2 = puterea2 * 62 % M2;
		}
	}

	for(int i=l_mic; i<l_mare; i++) {
		if(hash1 == rolling1 && hash2 == rolling2) {
			if(cate < 1000) rezultate[cate] = i-l_mic;
			cate++;
		}

		const int ce_scot_1 = lookup(mare[i-l_mic]) * puterea1 % M1,
			ce_scot_2 = lookup(mare[i-l_mic]) * puterea2 % M2;

		rolling1 = ((rolling1 - ce_scot_1 + M1) % M1 	// scoate primul
					* 62 + lookup(mare[i])) % M1;		// baga urmatorul
		
		rolling2 = ((rolling2 - ce_scot_2 + M2) % M2 * 62 + lookup(mare[i])) % M2;
	}

	FILE *fout = fopen("strmatch.out", "w");
	fprintf(fout, "%d\n", cate);
	for(int i=0; i<cate; i++)
		fprintf(fout, "%d ", rezultate[i]);
	fprintf(fout, "\n");
	fclose(fout);

	return 0;
}