Cod sursa(job #3369406)

Utilizator Emre12Isleam Emre Emre12 Data 20 octombrie 2026 10:27:31
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <string>
#include <vector>

#define R1 432314 // random 1 (este random ptc l am tastat eu random)
#define R2 130333
#define R3 213023
#define HASH_SIZE 65536 // cate valori are un unsigned short

unsigned short
powShort(unsigned b,
         unsigned exp) { // pow care automat face modulo 2^16 cand da overflow
  unsigned rez = 1;

  while (exp) {
    if (exp % 2)
      rez *= b;
    b *= b;
    exp /= 2;
  }

  return (unsigned short)rez;
}
struct rhash {
  const unsigned short putMax;
  const int r;
  rhash(int r, unsigned short k)
      : putMax(powShort(r, k - 1)), r(r) {} // constructor
  // precalculare r^k-1 , ca sa pot scoate ult element usor k = lungimea
  // substringului

  unsigned short hash(const std::string &a) {
    unsigned short rez = 0;

    for (int i = 0; i < a.size(); i++)
      rez = (unsigned short)((long long)rez * r + a[i]);

    return rez;
  }

  unsigned short roll(unsigned short hash, unsigned char oldChar,
                      unsigned char newChar) {
    hash -= oldChar * putMax;
    hash = hash * r + newChar;

    return hash;
  }
};
int main() {
  FILE *fout;
  std::ifstream fin("strmatch.in");
  fout = fopen("strmatch.out", "w");

  std::vector<int> rasp;
  std::string a, b;
  fin >> a >> b;
  int i = a.size();

  rhash h1(R1, a.size()), h2(R2, a.size()),
      h3(R3, a.size()); // doua functii hash, ca sa fie sansele mai mici sa dea
                        // 2 stringuri acelasi hash

  int orHash = h1.hash(a), orHash2 = h2.hash(a),
      orHash3 = h3.hash(a); // hashurile lui a

  int currentHash = h1.hash(b.substr(0, i)),
      currentHash2 = h2.hash(b.substr(0, i)),
      currentHash3 = h3.hash(b.substr(0, i));

  if (currentHash == orHash && currentHash2 == orHash2 &&
      currentHash3 == orHash3)
    rasp.push_back(0);

  while (i < b.size()) {
    currentHash = h1.roll(currentHash, b[i - a.size()], b[i]);
    currentHash2 = h2.roll(currentHash2, b[i - a.size()], b[i]);
    currentHash3 = h3.roll(currentHash3, b[i - a.size()], b[i]);

    if (currentHash == orHash && currentHash2 == orHash2 &&
        currentHash3 == orHash3)
      rasp.push_back(i - a.size() + 1);

    i++;
  }

  fprintf(fout, "%d\n", (int)rasp.size());
  for (int i = 0; i < std::min((int)rasp.size(), 1000); i++)
    fprintf(fout, "%d ", rasp[i]);

  return 0;
}