vendredi 23 mars 2018

C++11 code explanation needed

This is a very specific question. So, presumably we have to input 2 strings of maximum length of 125000 chars each. Second is smaller than the first one. All I know is that there supposed to be lots of substrings comparisons, but I'm not sure what exactly. So I have a code in C++ but need explanation of how it works, if not all, then maybe some important points. Help is much appreciated. So here is the code:

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;
typedef unsigned long long ull;

#define PB push_back
#define fi first
#define se second
#define MP make_pair

const int maxN = 200000 + 10;

char S[maxN], T[maxN];
int ns, nt;
ull po[maxN];
ull ps[64], pt[64];
vector<int> ss;
vector<int> super[6];

bool ss_less(int a, int b) {
  return __builtin_popcount(a) < __builtin_popcount(b);
}

int main() {
  //
  po[0] = 1;
  for (int i = 1; i < maxN; i++)
    po[i] = po[i-1]*5;
  for (int s = 0; s < (1<<6); s++) {
    ss.push_back(s);
    for (int i = 0; i < 6; i++) if ((s>>i)&1) {
      super[i].push_back(s);
    }
  }
  sort(ss.begin(), ss.end(), ss_less);
  //
  scanf("%s", S); ns = strlen(S);
  scanf("%s", T); nt = strlen(T);
  memset(ps, 0, sizeof ps);
  memset(pt, 0, sizeof pt);
  for (int i = 0; i < nt; i++) {
    for (auto s: super[T[i]-'a'])
      pt[s] += po[i];
  }

  // prepare s
  for (int i = 0; i < nt; i++) {
    for (auto s: super[S[i]-'a'])
      ps[s] += po[i];
  }
  for (int i = 0; i+nt <= ns; i++) {
    //
    int cs = 0, res = 0;
    for (auto s: ss) if ((s&cs) == 0) {
      if (pt[s] == 0 && ps[s] == 0) {
        cs |= s;
        continue;
      }
      if (pt[s]*po[i] == ps[s]) {
        res += __builtin_popcount(s) - 1;
        cs |= s;
        continue;
      }
    }
    printf("%d ", res);
    // update super
    if (i+nt < ns) {
      for (auto s: super[S[i]-'a']) {
        ps[s] -= po[i];
      }
      for (auto s: super[S[i+nt]-'a']) {
        ps[s] += po[i+nt];
      }
    }
  }
  printf("\n");
  return 0;
}

Aucun commentaire:

Enregistrer un commentaire