Cod sursa(job #1399299)

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

using namespace std;

typedef unsigned long long BigUnsigned;

namespace Consts {
	const BigUnsigned mod = 666013;
	const BigUnsigned p = 101;
	BigUnsigned p_n;
};

BigUnsigned fast_pow(BigUnsigned b, BigUnsigned e) {
	if(e == 0) return 1;
	if(e == 1) return b%Consts::mod;

	if(e%2 == 0) {
		return fast_pow(b*b,e/2)%Consts::mod;
	}
	else {
		return (b*fast_pow(b*b,e/2))%Consts::mod;
	}
}

BigUnsigned step_hash(BigUnsigned init_hash, char to_add, char to_remove) {
	BigUnsigned next_hash = init_hash + Consts::mod - (to_remove*Consts::p_n)%Consts::mod;
	next_hash *= Consts::p;
	next_hash += to_add;
	return next_hash % Consts::mod;
}

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

	Consts::p_n = fast_pow(Consts::p,small.size()-1);

	BigUnsigned small_hash=0;

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

	vector<unsigned> solutions;

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

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

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

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

	return 0;
}