| # | Time | Username | Problem | Language | Result | Execution time | Memory | 
|---|---|---|---|---|---|---|---|
| 298767 | Pro_ktmr | Monochrome Points (JOI20_monochrome) | C++14 | 2062 ms | 262540 KiB | 
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
const int dx[4]={ 1,0,-1,0 };
const int dy[4]={ 0,1,0,-1 };
template<typename T>
struct TreapSet{
private:
    struct Node{
        T x; // value
        int p; // priority
        Node* par; // parent
        Node* chi[2]; // children
        int s; // size of subtree
        T m; // minimum value of subtree
        Node(T _x, std::mt19937& mt){
            x = _x;
            p = mt();
            par = NULL;
            chi[0] = NULL;
            chi[1] = NULL;
            s = 1;
            m = _x;
        }
        bool operator==(const Node& u){
            return x == u.x;
        }
        bool operator<(const Node& u){
            return x < u.x;
        }
    };
    int N;
    Node* root;
    std::mt19937 mt;
    Node* find(T _x){
        Node* u = root;
        while(u != NULL && u->x != _x){
            if(u->x > _x) u = u->chi[0];
            else u = u->chi[1];
        }
        return u;
    }
    void update(Node* u){
        u->s = (u->chi[0] != NULL ? u->chi[0]->s : 0) + (u->chi[1] != NULL ? u->chi[1]->s : 0) + 1;
        u->m = u->x;
        if(u->chi[0] != NULL && u->chi[0]->m < u->m) u->m = u->chi[0]->m;
        if(u->chi[1] != NULL && u->chi[1]->m < u->m) u->m = u->chi[1]->m;
    }
    void rotateRight(Node* u){
        Node* p = u->par;
        u->par = p->par;
        if(p->par != NULL){
            if(p->par->chi[0] == p) p->par->chi[0] = u;
            else p->par->chi[1] = u;
        }
        p->par = u;
        p->chi[0] = u->chi[1];
        if(u->chi[1] != NULL) u->chi[1]->par = p;
        u->chi[1] = p;
        update(p);
        update(u);
    }
    void rotateLeft(Node* u){
        Node* p = u->par;
        u->par = p->par;
        if(p->par != NULL){
            if(p->par->chi[0] == p) p->par->chi[0] = u;
            else p->par->chi[1] = u;
        }
        p->par = u;
        p->chi[1] = u->chi[0];
        if(u->chi[0] != NULL) u->chi[0]->par = p;
        u->chi[0] = p;
        update(p);
        update(u);
    }
    void bubbleUp(Node* u){
        while(u->par != NULL && u->par->p > u->p){
            if(u->par->chi[0] == u) rotateRight(u);
            else rotateLeft(u);
        }
        if(u->par == NULL) root = u;
    }
public:
    TreapSet(){
        N = 0;
        root = NULL;
        std::mt19937 mt2(869120);
        mt = mt2;
    }
    void add(T _x){
        Node* u = new Node(_x, mt);
        if(N == 0){
            root = u;
        }
        else{
            Node* p = root;
            Node* v = root;
            while(v != NULL){
                p = v;
                p->s++;
                if(p->m > _x) p->m = _x;
                if(v->x > _x) v = v->chi[0];
                else v = v->chi[1];
            }
            if(p->x > _x){
                p->chi[0] = u;
                u->par = p;
            }
            else{
                p->chi[1] = u;
                u->par = p;
            }
            bubbleUp(u);
        }
        N++;
    }
    int lower_bound(T _x){
        Node* u = root;
        bool seted = false;
        T ret;
        while(u != NULL){
            if(u->x >= _x && (!seted || u->x < ret)){
                ret = u->x;
                seted = true;
            }
            if(u->chi[0] == NULL) u = u->chi[1];
            else if(u->chi[1] == NULL) u = u->chi[0];
            else if(u->chi[1]->m <= _x) u = u->chi[1];
            else{
                if(!seted || ret > u->chi[1]->m){
                    ret = u->chi[1]->m;
                    seted = true;
                }
                u = u->chi[0];
            }
        }
        if(!seted) return N;
        return index(ret);
    }
    int index(T _x){
        Node* u = root;
        int ret = 0;
        while(u != NULL && u->x != _x){
            if(u->x > _x) u = u->chi[0];
            else{
                ret += (u->chi[0] != NULL ? u->chi[0]->s : 0) + 1;
                u = u->chi[1];
            }
        }
        if(u == NULL) return -1;
        if(u->chi[0] != NULL) ret += u->chi[0]->s;
        return ret;
    }
};
void rotate(vector<pair<int,int>> &v, int idx){
    vector<pair<int,int>> ret;
    for(int i=idx; i<v.size(); i++) ret.pb(v[idx]);
    rep(i, idx) ret.pb(v[i]);
    v = ret;
}
void merge(vector<pair<int,int>> &a, vector<pair<int,int>> &b){
    int N = a.size() + b.size();
    int i = a.size()-1; int j = b.size()-1;
    a.resize(N);
    for(int k=N-1; k>=0; k--){
        if(i == -1){
            a[k] = b[j];
            j--;
        }
        else if(j == -1){
            a[k] = a[i];
            i--;
        }
        else if(a[i] > b[j]){
            a[k] = a[i];
            i--;
        }
        else{
            a[k] = b[j];
            j--;
        }
    }
}
int N;
char S[400001];
vector<int> B, W;
ll memo[200000];
ll solve(int i){
    if(memo[i] != -1) return memo[i];
    vector<pair<int,int>> v, v2;
    rep(j, N){
        int a = B[j];
        int b = W[(i+j)%N];
        if(a > b){
            v.pb({a, b});
        }
        else{
            v2.pb({b, a});
        }
    }
    rep(j, (int)v2.size()-1){
        if(v2[j] > v2[j+1]){
            rotate(v2, j+1);
            break;
        }
    }
    merge(v, v2);
    TreapSet<int> st;
    ll tmp = 0;
    for(int j=N-1; j>=0; j--){
        tmp += st.lower_bound(v[j].first) - st.lower_bound(v[j].second+1);
        st.add(v[j].second);
    }
    return memo[i] = tmp;
}
signed main(){
    scanf("%d", &N);
    scanf("%s", S);
    rep(i, 2*N){
        if(S[i] == 'B') B.pb(i);
        if(S[i] == 'W') W.pb(i);
    }
    memset(memo, -1, sizeof(memo));
    ll ans = 0;
    int v = (N+1) / 2;
    int n = 0;
    while(v > 0){
        ll a1 = solve(n);
        ll a2 = solve((n+1)%N);
        ans = max({ans,a1,a2});
        if(a1 >= a2) n = (n-v+N) % N;
        else n = (n+v) % N;
        if(v == 1) break;
        v = (v+1) / 2;
    }
    printf("%lld\n", ans);
}
Compilation message (stderr)
| # | Verdict | Execution time | Memory | Grader output | 
|---|---|---|---|---|
| Fetching results... | ||||
| # | Verdict | Execution time | Memory | Grader output | 
|---|---|---|---|---|
| Fetching results... | ||||
| # | Verdict | Execution time | Memory | Grader output | 
|---|---|---|---|---|
| Fetching results... | ||||
| # | Verdict | Execution time | Memory | Grader output | 
|---|---|---|---|---|
| Fetching results... | ||||
