Cod sursa(job #1495355)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 2 octombrie 2015 22:59:10
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.55 kb
#include <fstream>
#include <iostream>
#include <numeric>
#include <algorithm>
#include <vector>
#include <array>
using namespace std;

class suffix_array{
	int n;
	vector<int> sa;
	vector<array<int, 18> > ord;
	int compare(const int p1, const int p2, const int niv){
		const int step = 1<<(niv-1);
		const int v1 = ord[p1][niv-1], v2 = ord[p2][niv-1],
			w1 = (p1+step < n ? ord[p1+step][niv-1] : -1),
			w2 = (p2+step < n ? ord[p2+step][niv-1] : -1);
		return v1 < v2 ? -1 :
			v1 > v2 ? 1 :
			w1 < w2 ? -1 :
			w1 > w2 ? 1 : 0; }
public:
	suffix_array(const string str):
		n(str.size()), sa(n), ord(n, array<int, 18>({})){
		iota(begin(sa), end(sa), 0);
		for(int i = 0; i < n; ++i){
			ord[i][0] = str[i]; }
		for(int niv = 1; niv < 18; ++niv){
			sort(begin(sa), end(sa), [this, niv](const int p1, const int p2){
				return compare(p1, p2, niv) < 0; });
			ord[sa[0]][niv] = 0;
			for(int i = 1, val = 0; i < n; ++i){
				if(compare(sa[i-1], sa[i], niv) != 0){
					++val; }
				ord[sa[i]][niv] = val; } } }
	int lcp(const int sa_1, const int sa_2){
		if(sa_1 == sa_2){
			return n - sa[sa_1]; }
		int rez = 0;
		for(int niv = 16; niv >= 0; --niv){
			int v1 = (sa[sa_1]+rez < n ? ord[sa[sa_1]+rez][niv] : -1),
				v2 = (sa[sa_2]+rez < n ? ord[sa[sa_2]+rez][niv] : -1);
			if(v1 == v2){
				rez += (1<<niv); } }
		return rez; } };

int main(){
	ifstream f("substr.in");
	ofstream g("substr.out");
	int n, k;
	f >> n >> k;
	string str;
	f >> str;
	suffix_array sa(str);
	int rez = 0;
	for(int i = 0, j = k-1; j < n; ++i, ++j){
		rez = max(rez, sa.lcp(i, j)); }
	g << rez;
	return 0; }