Cod sursa(job #1399353)

Utilizator alexandru70Ungurianu Alexandru alexandru70 Data 24 martie 2015 18:26:57
Problema Potrivirea sirurilor Scor 26
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <fstream>
#include <vector>
#include <iostream>

using namespace std;

typedef long long BigUnsigned;

namespace Consts {
	const BigUnsigned mod = 666013;
	const BigUnsigned p = 301;
	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)%Consts::mod,e/2)%Consts::mod;
	}
	else {
		return (b*fast_pow((b*b)%Consts::mod,e/2))%Consts::mod;
	}
}

BigUnsigned step_hash(BigUnsigned init_hash, char to_add, char to_remove) {
	return ((Consts::p * (init_hash + Consts::mod - (Consts::p_n*to_remove)%Consts::mod))%Consts::mod + to_add)%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);
	}

	unsigned count = 0;
	if(big_hash == small_hash) {
		solutions.push_back(0);
		count++;
	}
	ofstream out("strmatch.out");
	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);
			}
			count ++;
		}
	}

	out << count << '\n';
	for(unsigned s:solutions) {
		out << s << ' ';
	}
	out << '\n';

	return 0;
}