Pagini recente » Cod sursa (job #853966) | Cod sursa (job #1468092) | Cod sursa (job #2397488) | Cod sursa (job #2349542) | Cod sursa (job #1697863)
#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;
}