Cod sursa(job #2794834)

Utilizator YusyBossFares Yusuf YusyBoss Data 5 noiembrie 2021 15:24:09
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <fstream>
#include <vector>
#include <map>
#define NHASH1 100007 /// numar satanist
#define NHASH2 100021 /// inca un numar satanist
#define BHASH 63
#define NMAX 2000000

using namespace std;

ifstream cin ("strmatch.in");
ofstream cout ("strmatch.out");

vector <int> vsol;
map<char, int> mpval;

int add_ch(int current_hash, char ch, int base, int MOD) {
  return ((current_hash * base) % MOD + mpval[ch]) % MOD;
}

int del_ch(int current_hash, char ch, int pow, int MOD) {
  return (current_hash - (mpval[ch] * pow) % MOD + MOD) % MOD;
}

void prec_mpval() {
  int cnt = 0;
  char ch;

  for (ch = 'a'; ch <= 'z'; ch++)
    mpval[ch] = cnt++;
  for (ch = 'A'; ch <= 'Z'; ch++)
    mpval[ch] = cnt++;
  for (ch = '0'; ch <= '9'; ch++)
    mpval[ch] = cnt++;
}

int lgput(int base, int exp, int MOD) {
  if (exp == 0)
    return 1;

  int sol;
  sol = lgput(base, exp / 2, MOD);
  sol = ((long long)sol * sol) % MOD;
  if (exp % 2 == 1)
    sol = ((long long)sol * base) % MOD;

  return sol;
}

int main() {
  int pow1, pow2, pattern_hash1, current_hash1, pattern_hash2, current_hash2, ns, np, i, nsol;
  string pattern, s;
  cin >> pattern >> s;

  ns = s.size();
  np = pattern.size();

  prec_mpval();
  pow1 = lgput(BHASH, np - 1, NHASH1);
  pow2 = lgput(BHASH, np - 1, NHASH2);

  pattern_hash1 = current_hash1 = pattern_hash2 = current_hash2 = 0;
  for (i = 0; i < np; i++) {
    pattern_hash1 = add_ch(pattern_hash1, pattern[i], BHASH, NHASH1);
    current_hash1 = add_ch(current_hash1, s[i], BHASH, NHASH1);

    pattern_hash2 = add_ch(pattern_hash2, pattern[i], BHASH, NHASH2);
    current_hash2 = add_ch(current_hash2, s[i], BHASH, NHASH2);
  }

  if (current_hash1 == pattern_hash1 && current_hash2 == pattern_hash2)
    vsol.push_back(0);

  for (i = np; i < ns; i++) {
    current_hash1 = add_ch(del_ch(current_hash1, s[i - np], pow1, NHASH1), s[i], BHASH, NHASH1);
    current_hash2 = add_ch(del_ch(current_hash2, s[i - np], pow2, NHASH2), s[i], BHASH, NHASH2);

    if (current_hash1 == pattern_hash1 && current_hash2 == pattern_hash2)
      vsol.push_back(i - np + 1);
  }

  cout << vsol.size() << "\n";
  for (i = 0; i < vsol.size() && i < 1000; i++)
    cout << vsol[i] << " ";
  return 0;
}