Untitled

mail@pastecode.io avatar
unknown
c_cpp
10 months ago
2.9 kB
7
Indexable
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>

using namespace std;

void PrintDataMerged(std::vector<uint64_t>& data) {
	for (int n : data) {
		std::cout << n << " ";
	}
	std::cout << std::endl;
}

std::vector<uint64_t> GenFoundations(uint64_t foundation, uint64_t mod, size_t size) {
	std::vector<uint64_t> foundations;
	foundations.reserve(size);
	uint64_t rand = 1;
		while (size--) {
			foundations.push_back(rand);
		rand = (rand * foundation) % mod;
	}
	return foundations;
}

inline int Hash(std::string& word, std::vector<uint64_t>& foundations, uint64_t mod) {
	uint64_t hash = 0;
	int counter = 0;
	for (int i = word.size() - 1; i >= 0; --i) {
		hash += foundations.at(counter++) * (uint64_t(word.at(i)) % mod) ;

	}
	return hash  % mod;
}

std::vector<uint64_t> CacheStringHashes(std::string& word, uint64_t foundations, uint64_t mod) {
	std::vector<uint64_t> result;
	result.reserve(word.size());
	uint64_t hash = 0;
	//int counter = 0;
	for(char c : word) {
		hash = (hash * foundations + uint64_t(c)) % mod;
		result.push_back(hash);
	}
	return result;
}


int main() {
	std::ios::sync_with_stdio(false);
	uint64_t foundation, mod;
	std::cin >> foundation;
	std::cin.get();
	std::cin >> mod;
	std::cin.get();
	std::string word;
	std::getline(std::cin, word);
	int counter;
	std::cin >> counter;
	std::cin.get();
	std::vector<uint64_t> foundations_cache(GenFoundations(foundation, mod, word.size()));
	std::vector<uint64_t> str_hashes(CacheStringHashes(word, foundation, mod));
	// PrintDataMerged(str_haches);
//	std::cout << "'abcd - ab = cd' : " <<  uint64_t(225227) - foundations_cache.at(2) * uint64_t(97098) % mod << " exp. 99100" << std::endl;
//	std::cout << "'abcdefgh - abcdef = gh' : " <<  uint64_t(436420) - foundations_cache.at(2) * uint64_t(74077) % mod << " exp. 103104" << std::endl;
//	std::cout << "'abcdefgh - abcd = efgh' : "  <<  uint64_t(436420) - foundations_cache.at(4) * uint64_t(225227) % mod << " exp. 193195" << std::endl;
//	std::cout << "'ab - a = b' : " <<  uint64_t(97098) - foundations_cache.at(1) * uint64_t(97) % mod << " exp. 98" << std::endl;
//	std::cout << "'abcd - a = bcd' : " <<  uint64_t(225227) - foundations_cache.at(3) * uint64_t(97) % mod << " exp. 98218" << std::endl;
//	std::cout << std::endl;
//	std::cout << "'abc - a = bc' :" <<  uint64_t(97226) - foundations_cache.at(0) * uint64_t(98) % mod << " exp. 98099" << std::endl;
	while (counter) {
		uint64_t begin, end;
		std::cin >> begin >> end;
		std::cin.get();
		--counter;
		uint64_t end_hash = str_hashes.at(end - 1);

		if (begin > 1) {
			int diff = end - begin;
			if (!diff) {
				std::cout << int(word.at(begin - 1))  << std::endl;
			} else {
				uint64_t begin_hash =  str_hashes.at(begin - 2);
				std::cout <<  end_hash - foundations_cache.at(end-begin + 1) * begin_hash % mod << std::endl;			}
		} else {
			std::cout << end_hash  << std::endl;
		}
	}
	return 0;
}

Leave a Comment