Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <cmath>
- #include <string>
- #include <unordered_map>
- #include <unordered_set>
- #include <map>
- #include <set>
- #include <queue>
- #include <ostream>
- #include <istream>
- #include <typeinfo>
- #include <iomanip>
- #include <cstdio>
- #include <cstdlib>
- #include <cassert>
- #include <limits>
- #include <fstream>
- #include <array>
- #include <list>
- #include <bitset>
- #include <functional>
- #define mt make_tuple
- #define x first
- #define y second
- #define pb push_back
- #define ppb pop_back
- #define pf push_front
- #define ppf pop_front
- #define mp make_pair
- #define umap unordered_map
- #define uset unordered_set
- #define rt return 0;
- #define elif else if
- #define len(v) ((int)v.size())
- using namespace std;
- char string_in_buffer[(int)2e6];
- void fast_scan(int &x) { scanf("%d", &x); }
- void fast_scan(long long &x) { scanf("%lld", &x); }
- void fast_scan(unsigned long long &x) { scanf("%llu", &x); }
- void fast_scan(double &x) { scanf("%lf", &x); }
- void fast_scan(long double &x) { scanf("%Lf", &x); }
- void fast_scan(char &x) {
- scanf("%c", &x);
- if (x == '\n') {
- fast_scan(x);
- }
- }
- void fast_scan(string &x) {
- scanf("%s", string_in_buffer);
- x = string(string_in_buffer);
- }
- template<class TFirst, class TSecond>
- void fast_scan(pair<TFirst, TSecond> &p) {
- fast_scan(p.first);
- fast_scan(p.second);
- }
- template <class T>
- void fast_scan(vector<T> &v) {
- for (auto &x : v) fast_scan(x);
- }
- void fast_print(const int &x) { printf("%d", x); }
- void fast_print(const long long &x) { printf("%lld", x); }
- void fast_print(const unsigned long long &x) { printf("%llu", x); }
- void fast_print(const double &x) { printf("%.15lf", x); }
- void fast_print(const long double &x) { printf("%.15Lf", x); }
- void fast_print(const char &x) { printf("%c", x); };
- void fast_print(const string &x) { printf("%s", x.c_str());}
- template<class TFirst, class TSecond>
- void fast_print(const pair<TFirst, TSecond> &p) {
- fast_print(p.first);
- fast_print(' ');
- fast_print(p.second);
- }
- template <class T>
- void fast_print(const vector<T> &v) {
- if (v.empty()) return;
- fast_print(v[0]);
- for (int i = 1; i < v.size(); i++) {
- fast_print(" ");
- fast_print(v[i]);
- }
- }
- template <class T>
- void fast_print(const vector<vector<T>> &v) {
- if (v.empty()) return;
- fast_print(v[0]);
- for (int i = 1; i < v.size(); i++) {
- fast_print("\n");
- fast_print(v[i]);
- }
- }
- using namespace std;
- namespace smart_io {
- string print_start = "";
- string sep = " ";
- bool first_print = false;
- void precall_print() {
- fast_print(print_start);
- print_start = "\n";
- first_print = true;
- }
- } //namespace smart_io
- template <class T>
- ostream &operator,(ostream &os, const T &object) {
- if (!smart_io::first_print) {
- fast_print(smart_io::sep);
- } else {
- smart_io::first_print = false;
- }
- fast_print(object);
- return os;
- }
- template <class T>
- istream &operator,(istream &is, T &object) {
- fast_scan(object);
- return is;
- }
- namespace typedefs {
- typedef long long ll;
- typedef unsigned long long ull;
- typedef pair<int, int> pii;
- }
- namespace numbers_operation {
- template<class T>
- T floor_mod(T a, T b) {
- if (a % b == 0) return 0;
- if (a >= 0 && b >= 0) return a % b;
- if (a <= 0 && b <= 0) return a % b;
- return abs(b) - (abs(a) % abs(b));
- }
- }
- using namespace numbers_operation;
- using namespace typedefs;
- #define print \
- smart_io::precall_print(); \
- cout,
- #define scan cin,
- template <class T, class T_Magic>
- class SparseTable {
- public:
- T_Magic magic;
- vector<int> two_powers{1};
- vector<int> max_pow2;
- vector<vector<T>> tree;
- private:
- int next_2log(int n) {
- int x = log2(n);
- if (n != pow(x, 2)) {
- x++;
- }
- return x;
- }
- T __query(int left, int right) {
- int block = max_pow2[right - left + 1];
- return magic(tree[block][left], tree[block][right - (two_powers[block]) + 1]);
- }
- public:
- SparseTable(vector<T> &v, T_Magic magic):magic(magic) {
- int n = v.size();
- int logn = log2(n) + 1;
- if (two_powers.empty()) {
- two_powers.pb(1);
- }
- while (two_powers.size() <= logn) {
- two_powers.pb(2 * two_powers[two_powers.size() - 1]);
- }
- // max_pow2 construction
- max_pow2.resize(n + 1, 1);
- int cur_pow = 1;
- int cur_log = 0;
- for (int i = 0; i < n + 1; i++) {
- if (i >= cur_pow) {
- cur_pow *= 2;
- cur_log++;
- }
- max_pow2[i] = max(cur_log - 1, 0);
- }
- // cout << max_pow2 << nl;
- // exit(0);
- tree.resize(logn, vector<T> (n));
- tree[0] = v;
- construct_tree();
- };
- void construct_tree() {
- for (int i = 1; i < tree.size(); i++) {
- for (int j = 0; j < tree[i].size(); j++) {
- int next_block = j + two_powers[i - 1];
- tree[i][j] = tree[i - 1][j];
- if (next_block < tree[i - 1].size()) {
- tree[i][j] = magic(tree[i][j], tree[i - 1][next_block]);
- }
- }
- }
- }
- // calcs magic in [L:R)
- T query(int left, int right) {
- right--;
- if (left > right) {
- tie(left, right) = mt(right, left);
- }
- return __query(left, right);
- }
- };
- vector<int> get_p(const string &s) {
- int n = len(s);
- vector<int> pref(n);
- for (int i = 0; i < n; i++) {
- pref[i] = (s[i] == 'j') ? -1 : 1;
- if (i > 0) {
- pref[i] += pref[i - 1];
- }
- }
- auto magic = [](const int &a, const int &b){
- return min(a, b);
- };
- SparseTable<int, decltype(magic)> sp(pref, magic);
- vector<int> p(n, 0);
- for (int i = 0; i < n; i++) {
- if (s[i] == 'j') {
- p[i] = i;
- continue;
- }
- int pr = (i == 0) ? 0 : pref[i - 1];
- int left = i + 1;
- int right = n + 1;
- while (right - left > 1) {
- int mid = (left + right) / 2;
- if (sp.query(i, mid) >= pr) {
- left = mid;
- } else {
- right = mid;
- }
- }
- p[i] = left;
- }
- return p;
- }
- signed main(signed argc, char *argv[]) {
- int n;
- scan n;
- string s;
- scan s;
- auto p = get_p(s);
- reverse(s.begin(), s.end());
- auto q = get_p(s);
- reverse(s.begin(), s.end());
- reverse(q.begin(), q.end());
- for (int i = 0; i < n; i++) {
- q[i] = n - q[i];
- }
- // print q;
- auto magic = [](const int &a, const int &b) {
- return min(a, b);
- };
- int _max = 0;
- SparseTable<int, decltype(magic)> sp(q, magic);
- for (int i = 0; i < n; i++) {
- if (p[i] == i) continue;
- int r = p[i] - 1;
- int left = -1;
- int right = (r - i);
- while (right - left > 1) {
- int mid = (left + right) / 2;
- if (sp.query(r - mid, r + 1) <= i) {
- right = mid;
- } else {
- left = mid;
- }
- }
- _max = max(_max, (r - right) - i + 1);
- }
- print _max;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement