Cod sursa(job #1697863)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 3 mai 2016 01:21:54
Problema Radix Sort Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.31 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

const int N_MAX = 100050;
const int LOG_MAX = 17;

int n;
char a[N_MAX];
int p[LOG_MAX + 1][2 * N_MAX];
pair<pair<int, int>, int> suf[N_MAX];
map<int, int> sufMap;
vector<pair<pair<int, int>, int>> bucket[N_MAX];

int GetElement(const pair<pair<int, int>, int> &p, bool indx) {
   if(indx == 0)
      return p.first.first;
   return p.first.second;
}

void CountingSort(bool indx) {
   for(int i = 0; i < n; i++) {
      bucket[GetElement(suf[i], indx) + 1].push_back(suf[i]);
   }
   for(int i = 0, j = 0; i <= max(n, 150); i++) {
      while(bucket[i].size() > 0) {
         suf[j++] = bucket[i].back();
         bucket[i].pop_back();
      }
   }
}

void PairSort() {
   CountingSort(1);
   CountingSort(0);
}

void BuildSuffixArray() {
   memset(p, -1, sizeof p);

   for(int i = 0; i < n; i++)
      p[0][i] = a[i];

   for(int i = 0; i < LOG_MAX; i++) {
      for(int j = 0; j < n; j++) {
         suf[j].first = make_pair(p[i][j], p[i][j + (1 << i)]);
         suf[j].second = j;
      }
      PairSort();
      for(int j = 0; j < n; j++) {
         p[i + 1][suf[j].second] = (j > 0 && suf[j - 1].first == suf[j].first ? p[i + 1][suf[j - 1].second] : j);
      }
   }
}

int Lcp(int x, int y) {
   if(x == y)
      return n - x;

   int ret = 0;
   for(int i = LOG_MAX; i >= 0; i--) {
      if(p[i][x] == p[i][y]) {
         ret |= 1 << i;
         x += 1 << i;
         y += 1 << i;
      }
   }

   return ret;
}

void Solve() {
   ofstream g("prefix2.out");

   int64_t crt;

   sufMap.insert(make_pair(p[LOG_MAX][n - 1], n - 1));

   g << (crt = 1) << '\n';

   for(int i = n - 2; i >= 0; i--) {
      map<int, int> :: iterator it;
      int usedPref;

      it = sufMap.lower_bound(p[LOG_MAX][i]);

      usedPref = (it != sufMap.end() ? Lcp(i, it->second) : 0);
      if(it != sufMap.begin()) {
         it--;
         usedPref = max(usedPref, Lcp(i, it->second));
      }

      crt += n - i - usedPref;
      sufMap.insert(make_pair(p[LOG_MAX][i], i));

      g << crt << '\n';
   }
}

int main() {
   ifstream("prefix2.in") >> a;

   n = strlen(a);
   reverse(a, a + n);

   BuildSuffixArray();
   Solve();

   return 0;
}