Cod sursa(job #1399258)

Utilizator alexandru70Ungurianu Alexandru alexandru70 Data 24 martie 2015 17:32:41
Problema Potrivirea sirurilor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
#include <vector>
#include <iostream>

using namespace std;

typedef unsigned long long BigUnsigned;

const BigUnsigned mod = 666013;

BigUnsigned p_pows[2000000];

void precalc_pows(BigUnsigned n) {
	static const BigUnsigned p = 101;
	p_pows[0] = 1;
	for(BigUnsigned i = 1; i < n; ++i) {
		p_pows[i] = (p*p_pows[i-1]);
	}
}

BigUnsigned step_hash(BigUnsigned init_hash, char to_add, char to_remove, BigUnsigned length) {
	return ((init_hash + mod - (p_pows[length-1]*static_cast<BigUnsigned>(to_remove))% mod )*p_pows[1] + static_cast<BigUnsigned>(to_add))%mod;
}

int main() {
	ifstream in("strmatch.in");
	string small,big;
	in >> small >> big;

	precalc_pows(small.size());

	BigUnsigned small_hash=0;

	for(char c:small) {
		small_hash = step_hash(small_hash,c,0,small.size());
	}

	vector<unsigned> solutions;

	BigUnsigned big_hash = 0;
	for(unsigned i = 0; i < small.size(); ++i) {
		big_hash = step_hash(big_hash,big[i],0,small.size());
	}

	if(big_hash == small_hash) {
		solutions.push_back(0);
	}

	for(unsigned i = 1; i < big.size()-small.size(); ++i) {
		big_hash = step_hash(big_hash,big[i+small.size()-1],big[i-1],small.size());
		if(big_hash == small_hash) {
			if(solutions.size() < 1000) {
				solutions.push_back(i);
			}
		}
	}

	ofstream out("strmatch.out");
	out << solutions.size() << '\n';
	for(unsigned s:solutions) {
		out << s << ' ';
	}
	out << '\n';

	return 0;
}