제출 #524768

#제출 시각아이디문제언어결과실행 시간메모리
524768cqtshadowArranging Shoes (IOI19_shoes)C++14
100 / 100
147 ms17688 KiB
#include <bits/stdc++.h>
#define MASK(x) (1LL << x)
#define GETBIT(mask, x) ((mask >> (x))&1)
#define ONBIT(mask, x) (mask | (1LL << (x)))
#define Each(type, i, a, b) for(type i = (a) ; i <= (b) ; ++i)
#define REach(type, i, a, b) for(type i = (a) ; i >= (b) ; --i)
using namespace std;

typedef long long ll;

const int N = 2e5 + 7;
const int MOD = 1e9 + 7;
const int INF = 2e9;
const double eps = 1e-9;
const ll oo = 4e18;

template<class X> bool maximize(X &x, X y) {return (x + eps < y ? x = y, true : false);}
template<class X> bool minimize(X &x, X y) {return (x > y + eps ? x = y, true : false);}

void add(int &x, int y) {x += y; if(x >= MOD) x -= MOD;}
void sub(int &x, int y) {x -= y; if(x < 0) x += MOD;}
int radd(int x, int y) {add(x, y); return x;}
int rsub(int x, int y) {sub(x, y); return x;}

string to2(int val) {bitset<10> temp(val); return temp.to_string();}

int n, lim;
int IT[4*N];

void update(int id, int val, int pos = 1, int l = 0, int r = lim) {
    if(id < l || id > r) return;
    if(l == r) {
        IT[pos] += val;
        return;
    }
    int mid = (l + r) >> 1;
    update(id, val, pos<<1, l, mid);
    update(id, val, pos<<1|1, mid + 1, r);
    IT[pos] = IT[pos << 1] + IT[pos<<1|1];
}

int get(int u, int v, int pos = 1, int l = 0, int r = lim) {
    if(u > v || v < l || r < u) return 0;
    if(u <= l && r <= v) return IT[pos];
    int mid = (l + r) >> 1;
    return get(u, v, pos<<1, l, mid) + get(u, v, pos<<1|1, mid + 1, r);
}

namespace SUB1 {
    ll solve(vector<int> S) {
        return S[0] > S[1];
    }
}

namespace SUB3 {
    vector<int> posi, nega;

    ll solve(vector<int> S) {
        Each(int, i, 0, lim) {
            if(S[i] < 0) nega.push_back(i);
            else posi.push_back(i);
            update(i, 1);
        }
        ll ans = 0;
        Each(int, i, 0, n - 1) {
            int l = min(nega[i], posi[i]);
            int r = max(nega[i], posi[i]);
            bool islastswap = (S[l] > 0);
            int sum = get(l + 1, r - 1);
            ans += sum + islastswap;
            update(r, -1);
        }

        return ans;
    }
}

namespace SUB4 {
    ll solve() {
        ll ans = 0;
        Each(int, i, 0, n - 1) {
            ans += (i + n) - i - 1 - i;
        }
        return ans;
    }
}

namespace SUB5 {
    bitset<2002> Marked;

    ll solve(vector<int> S) {
        ll ans = 0;
        Each(int, i, 0, lim) if(Marked[i] == 0) {
            int need = -S[i];
            int pos = i + 1;
            int sum = 0;
            while(true) {
                if(Marked[pos]) {++pos; continue;}
                if(S[pos] != need) {++sum; ++pos; continue;}
                break;
            }
            ans += sum + (S[i] > 0);
            Marked[pos] = 1;
        }
        return ans;
    }
}

namespace SUB6 {
    const int BONUS = 100000;
    vector<int> save[N];
    int pivot[N];
    bitset<200002> Marked;

    ll solve(vector<int> S) {
        Each(int, i, 0, lim) {
            save[BONUS + S[i]].push_back(i);
            update(i, 1);
        }
        ll ans = 0;
        Each(int, i, 0, lim) if(Marked[i] == 0) {
            int r = save[-S[i] + BONUS][pivot[-S[i] + BONUS]];
            bool islastswap = (S[i] > 0);
            int sum = get(i + 1, r - 1);
            ans += sum + islastswap;
            update(r, -1);
            Marked[r] = 1;
            pivot[S[i] + BONUS]++;
            pivot[-S[i] + BONUS]++;
        }
        return ans;
    }
}

ll count_swaps(vector<int> S) {
    n = S.size()/2;
    lim = 2*n - 1;
    bool issame = true; int ele = S[0];
    bool isdx = true; bool isseprate = true;

    Each(int, i, 0, lim) {
        issame &= (abs(ele) == abs(S[i]));
        if(i < n) isseprate &= (S[i] < 0);
        else isseprate &= (S[i] > 0);
    }

    Each(int, i, 0, n - 1)
        isdx &= (abs(S[i]) == abs(S[i + n]));

    if(isseprate && isdx) return SUB4::solve();

    if(issame) return SUB3::solve(S);

    if(n == 1) return SUB1::solve(S);

    if(n <= 1000) return SUB5::solve(S);

    return SUB6::solve(S);
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...