QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#691639#9244. Counting Stringsreal_sigma_teamWA 1ms3816kbC++234.6kb2024-10-31 12:22:552024-10-31 12:22:55

Judging History

This is the latest submission verdict.

  • [2024-10-31 12:22:55]
  • Judged
  • Verdict: WA
  • Time: 1ms
  • Memory: 3816kb
  • [2024-10-31 12:22:55]
  • Submitted

answer

#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()

// строка -- это последовательность чисел от 1 до размера алфавита
vector<int> suffix_array (vector<int> s) {
	if (s.size() == 1) {
		return vector<int>(1, 0);
	}
    s.push_back(0);  // добавляем нулевой символ в конец строки
    int n = (int) s.size(),
        cnt = 0,  // вспомогательная переменная: счётчик для сортировки 
        cls = 0;  // количество классов эквивалентности
    vector<int> c(n), p(n);
    
    map< int, vector<int> > t;
    for (int i = 0; i < n; i++)
        t[s[i]].push_back(i);
    
    // «нулевой» этап
    for (auto &x : t) {
        for (int u : x.second)
            c[u] = cls, p[cnt++] = u;
        cls++;
    }
    
    // пока все суффиксы не стали уникальными
    for (int l = 1; cls < n; l++) {
        vector< vector<int> > a(cls);  // массив для сортировки подсчётом
        vector<int> _c(n);  // новые классы эквивалентности
        int d = (1<<l)/2;
        int _cls = cnt = 0;  // новое количество классов
        
        for (int i = 0; i < n; i++) {
            int k = (p[i]-d+n)%n;
            a[c[k]].push_back(k);
        }
        
        for (int i = 0; i < cls; i++) {
            for (size_t j = 0; j < a[i].size(); j++) {
                // если суффикс начинает новый класс эквивалентности
                if (j == 0 || c[(a[i][j]+d)%n] != c[(a[i][j-1]+d)%n])
                    _cls++;
                _c[a[i][j]] = _cls-1;
                p[cnt++] = a[i][j];
            }
        }
        
        c = _c;
        cls = _cls;
    }
    
    return vector<int>(p.begin()+1, p.end());
}

vector<int> calc_lcp(vector<int> val, vector<int> c, vector<int> p) {
    int n = val.size();
    int current_lcp = 0;
    vector<int> lcp(n);
    for (int i = 0; i < n; i++) {
        if (c[i] == n - 1)
            continue;
        int nxt = p[c[i] + 1];
        while (max(i, nxt) + current_lcp < n && val[i + current_lcp] == val[nxt + current_lcp])
            current_lcp++;
        lcp[c[i]] = current_lcp;
        current_lcp = max(0, current_lcp - 1);
    }
    return lcp;
}

struct mst {
    vector<vector<int>> st;
    size_t sz;
    mst(const vector<int>& a) {
        sz = 1;
        while (sz < a.size()) {
            sz <<= 1;
        }
        st.resize(2 * sz);
        for (int i = 0; i < a.size(); i++) {
            st[sz + i].push_back(a[i]);
        }
        for (int i = sz - 1; i > 0; i--) {
            st[i].resize(st[2 * i].size() + st[2 * i + 1].size());
            merge(all(st[2 * i]), all(st[2 * i + 1]), st[i].begin());
        }
    }
    int get(int v, int l, int r) {
        l += sz;
        r += sz;
        int res = 0;
        while (l <= r) {
            if (l & 1) {
                res += upper_bound(all(st[l]), v) - st[l].begin();
                l++;
            }
            if (~r & 1) {
                res += upper_bound(all(st[r]), v) - st[r].begin();
                r--;
            }
            l >>= 1;
            r >>= 1;
        }
        return res;
    }
};


int32_t main() {
	std::cin.tie(nullptr)->sync_with_stdio(false);
	
	int n;
	cin >> n;
	string s;
	cin >> s;
	vector<int> a(n);
	for (int i = 0; i < n; i++) {
		a[i] = s[i];
	}
	vector<int> sa = suffix_array(a), osa(n);
	for (int i = 0; i < n; i++) {
		osa[sa[i]] = i;
	}
	long long ans = 0;
	vector<int> lcp = calc_lcp(a, osa, sa), lcpi(n);
	for (int i = n - 1; i > 0; i--) {
		lcp[i] = lcp[i - 1];
	}
	lcp[0] = 0;
	for (int i = 0; i < n; i++) {
		lcpi[sa[i]] = lcp[i];
	}
	mst st(lcp), st2(lcpi);
	for (int l = 0; l < n; l++) {
		if (l == 0) {
			ans++;
			continue;
		}
		if (l == 1) {
			ans += 2 * st.get(l, 0, n - 1);
			ans -= 2 * st2.get(l, n - l, n - 1);
			continue;
		}
		vector<int> bad(2);
		bad[0] = -1;
		bad[1] = n;
		for (int i = l - 1; i + l < n; i += l) {
			bad.push_back(osa[i]);
		}
		sort(all(bad));
		for (int i = 1; i < bad.size(); i++) {
			ans += 1ll * (l + 1) * st.get(l, bad[i - 1] + 1, bad[i] - 1);
			if (bad[i - 1]  >= 0 && bad[i - 1] + 1 != bad[i] && lcp[bad[i - 1] + 1] > l && lcp[bad[i - 1]] <= l && sa[bad[i - 1] + 1] + l < n) {
				ans += l + 1;
			}
		}
		ans -= 1ll * (l + 1) * st2.get(l, n - l, n - 1);
	}
	cout << ans << '\n';
}

詳細信息

Test #1:

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

input:

4
abca

output:

14

result:

ok answer is '14'

Test #2:

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

input:

1
a

output:

1

result:

ok answer is '1'

Test #3:

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

input:

2
aa

output:

3

result:

ok answer is '3'

Test #4:

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

input:

2
ab

output:

3

result:

ok answer is '3'

Test #5:

score: -100
Wrong Answer
time: 1ms
memory: 3540kb

input:

100
xgljgljgljjljjjjljtjljtgljgljgljjljjjjljtjljtjljgljljgljgljjljjjjljtjljtjljgljllljgllgljgljjglljgljl

output:

162782

result:

wrong answer expected '101808', found '162782'