QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#549298#5084. Longest SubstringBongoCatEnjoyerTL 0ms3676kbC++145.1kb2024-09-06 14:06:222024-09-06 14:06:23

Judging History

你现在查看的是最新测评结果

  • [2024-09-06 14:06:23]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3676kb
  • [2024-09-06 14:06:22]
  • 提交

answer

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

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

struct SuffixArray {
	vi sa, lcp;
	SuffixArray(string& s, int lim=256) { // or basic_string<int>
		int n = sz(s) + 1, k = 0, a, b;
		vi x(all(s)+1), y(n), ws(max(n, lim)), rank(n);
		sa = lcp = y, iota(all(sa), 0);
		for (int j = 0, p = 0; p < n; j = max(1, j * 2), lim = p) {
			p = j, iota(all(y), n - j);
			rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j;
			fill(all(ws), 0);
			rep(i,0,n) ws[x[i]]++;
			rep(i,1,lim) ws[i] += ws[i - 1];
			for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i];
			swap(x, y), p = 1, x[sa[0]] = 0;
			rep(i,1,n) a = sa[i - 1], b = sa[i], x[b] =
				(y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++;
		}
		rep(i,1,n) rank[sa[i]] = i;
		for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k)
			for (k && k--, j = sa[rank[i] - 1];
					s[i + k] == s[j + k]; k++);
	}
};

map<int,int> arrL;
map<int,int> arrR;
map< int, tuple<int,int,int,set<int>> > activeRange; // {L, R, len, set}
vector<int> ans;
vector<int> maxD;


void doCalc(int currRange){
    auto& tmp = activeRange[currRange];
    int l = get<0>(tmp);
    int r = get<1>(tmp);
    int len = get<2>(tmp);
    set<int> idxArr = get<3>(tmp);
    int d = 0;
    auto curr = idxArr.begin();
    while (curr != idxArr.end()){
        int currIdx = *curr;
        d++;
        curr = lower_bound(all(idxArr),currIdx+len);
    }
    // cout << "hasil d kiri = " << d << " " << l << " to " << r << endl;

    int nstring = r-l+2;
    if (maxD[nstring] < d){
        ans[nstring] = len;
        maxD[nstring] = d;
    } else if (maxD[nstring] == d){
        ans[nstring] = max(len,ans[nstring]);
    }
}

int main(){
    cin.tie(0)->sync_with_stdio(0);
    cin.exceptions(cin.failbit);
    string s;
    cin >> s;
    int n = s.length();
    SuffixArray sa = SuffixArray(s);

    // for (int i = 1;i <= n;i++){
    //     cout << sa.sa[i] << " ";
    // }
    // cout<< endl;

    // for (int i = 1;i <= n;i++){
    //     cout << sa.lcp[i] << " ";
    // }
    // cout<< endl;

    vector<pair<int,int>> sweepArr; // {lcp len, idx}
    for (int i = 1;i <= n;i++){
        if (sa.lcp[i] != 0) sweepArr.push_back({sa.lcp[i],i});
    } 
    sort(all(sweepArr), [](const pair<int,int> &a, const pair<int,int> &b){
        if (a.first == b.first){
            return a.second < b.second;
        }
        return a.first > b.first ;
    });

    ans.resize(n+1,0);
    maxD.resize(n+1,0);

    for (int i = 0;i < sweepArr.size();i++){
        int len = sweepArr[i].first;
        int curIdx = sweepArr[i].second;
        int suffIdx = sa.sa[curIdx];

        // cout << len << " " << curIdx << " " << suffIdx << endl;

        int leftRangeIdx = -1, rightRangeIdx = -1;
        if (arrR.count(curIdx-1)){
            leftRangeIdx = arrR[curIdx-1];
            doCalc(leftRangeIdx);
        }
        if (arrL.count(curIdx+1)){  
            rightRangeIdx = arrL[curIdx+1];
            doCalc(rightRangeIdx);
        }

        // cout << leftRangeIdx << " " << rightRangeIdx << endl;

        if (leftRangeIdx != -1 && rightRangeIdx != -1){
            auto lSuff = get<3>(activeRange[leftRangeIdx]);
            auto rSuff = get<3>(activeRange[rightRangeIdx]);
            lSuff.insert(all(rSuff));
            // lSuff.insert(suffIdx);

            arrR.erase(get<1>(activeRange[leftRangeIdx]));
            arrL.erase(get<1>(activeRange[rightRangeIdx]));
            arrL[get<1>(activeRange[rightRangeIdx])] = leftRangeIdx;

            get<1>(activeRange[leftRangeIdx]) = get<1>(activeRange[rightRangeIdx]);
            get<2>(activeRange[leftRangeIdx]) = len;
            activeRange.erase(rightRangeIdx);


        } else if (leftRangeIdx != -1){

            arrR.erase(get<1>(activeRange[leftRangeIdx]));
            arrR[curIdx] = leftRangeIdx;

            get<3>(activeRange[leftRangeIdx]).insert(suffIdx);
            get<1>(activeRange[leftRangeIdx]) = curIdx;
            get<2>(activeRange[leftRangeIdx]) = len;
        } else if (rightRangeIdx != -1){

            arrL.erase(get<1>(activeRange[rightRangeIdx]));
            arrL[curIdx] = rightRangeIdx;

            get<3>(activeRange[rightRangeIdx]).insert(sa.sa[curIdx-1]);
            get<0>(activeRange[rightRangeIdx]) = curIdx;
            get<2>(activeRange[rightRangeIdx]) = len;
        } else {

            activeRange[curIdx] = make_tuple(curIdx, curIdx, len, set<int>());
            get<3>(activeRange[curIdx]).insert(suffIdx);
            get<3>(activeRange[curIdx]).insert(sa.sa[curIdx-1]);
            arrL[curIdx] = curIdx;
            arrR[curIdx] = curIdx;
        }
    }

    for (auto& tmp : activeRange){
        // cout << tmp.first << endl;
        doCalc(tmp.first);
    }

    ans[1] = n;

    for (int i = 1;i <= n;i++){
        if (i != 1) cout << " ";
        cout << ans[i];
    }
    cout << endl;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3676kb

input:

ababa

output:

5 2 1 0 0

result:

ok single line: '5 2 1 0 0'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3644kb

input:

aaaaaaaa

output:

8 7 6 5 4 3 2 1

result:

ok single line: '8 7 6 5 4 3 2 1'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3568kb

input:

a

output:

1

result:

ok single line: '1'

Test #4:

score: 0
Accepted
time: 0ms
memory: 3572kb

input:

abcdefghijklmnopqrstuvwxyz

output:

26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

result:

ok single line: '26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'

Test #5:

score: -100
Time Limit Exceeded

input:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:


result: