답안 #799711

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
799711 2023-07-31T20:48:11 Z Johann Diversity (CEOI21_diversity) C++14
0 / 100
1 ms 340 KB
#include "bits/stdc++.h"
using namespace std;

typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pii;
typedef vector<pii> vpii;
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()

const ll INF = 1e18;
int N, Q;
int A[300007];
ll ans[50005];
int freq[300007];
int cnt[300007];
unordered_set<int> S;
int stuff[300007];
int idx;
ll tmp;
int pref, suff, n;

struct query
{
    int l, r, idx;
};

ll numberOfSubsequences(ll x)
{
    return x * (x + 1) / 2;
}
ll totalLengthOfSubsequences(ll x)
{
    return x * (x + 1) * (x + 2) / 6;
    // return x * (x + 1) * (x + 1) / 2 - (2 * x + 1) * (x + 1) * x / 6;
}
void doStuff(ll x, ll y)
{
    ll len = x * y;

    // if both are in set
    // tmp += x * x * (totalLengthOfSubsequences(y) - y) + y * numberOfSubsequences(x);
    tmp += x * x * (totalLengthOfSubsequences(y) - y) + y * x * (x + 1) / 2;

    // if one is inside the other isn't
    tmp += (n - len) * (x * y * (y + 1) / 2);
    // if both are outside
    tmp += y * pref * (n - pref - len);

    pref += len;
    swap(pref, suff);
}
struct segtree
{
    int arr[1 << 20];
    int size;
    void init(int _size)
    {
        size = 1;
        while (size < _size)
            size *= 2;
        fill(arr, arr + 2 * size, 0);
    }
    void add(int i, int v)
    {
        i += size;
        while (i > 0)
        {
            arr[i] += v;
            i /= 2;
        }
    }
    void dfs(int x)
    {
        if (arr[x] == 0)
            return;
        if (x < size)
        {
            dfs(2 * x);
            dfs(2 * x + 1);
        }
        else
        {
            // arr[x] := how often
            doStuff(x - size, (arr[x] + 1) / 2);
            if (arr[x] > 1)
            {
                doStuff(x - size, arr[x] / 2);
                if (arr[x] & 1)
                    swap(pref, suff);
            }
        }
    }
};
segtree seg;
void add(int x)
{
    if (freq[x] > 0)
    {
        // seg.add(freq[x], -1);
        --cnt[freq[x]];
        // if (cnt[freq[x]] == 0)
        //     S.erase(freq[x]);
    }
    ++freq[x];
    // seg.add(freq[x], 1);
    ++cnt[freq[x]];
    if (cnt[freq[x]] == 1)
        stuff[idx++] = freq[x];
}
void sub(int x)
{
    // seg.add(freq[x], -1);
    --cnt[freq[x]];
    // if (cnt[freq[x]] == 0)
    //     S.erase(freq[x]);
    --freq[x];
    if (freq[x])
    {
        // seg.add(freq[x], 1);
        ++cnt[freq[x]];
        if (cnt[freq[x]] == 1)
            stuff[idx++] = freq[x];
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> N >> Q;
    for (int i = 0; i < N; ++i)
        cin >> A[i];

    vector<query> Qu(Q);
    for (int i = 0; i < Q; ++i)
        cin >> Qu[i].l >> Qu[i].r, Qu[i].idx = i, --Qu[i].l;

    int sq = ceil(sqrt(N));
    auto cmp = [&](const query &a, const query &b)
    { if (a.l / sq == b.l / sq) 
        return a.r < b.r;
    else
        return a.l < b.l; };
    sort(all(Qu), cmp);

    int lx = 0, rx = 0;
    fill(freq, freq + *max_element(A, A + N) + 1, 0);
    fill(cnt, cnt + N + 3, 0);
    seg.init(N + 1);
    for (query q : Qu)
    {
        while (rx < q.r)
            add(A[rx++]);
        while (lx > q.l)
            add(A[--lx]);
        while (rx > q.r)
            sub(A[--rx]);
        while (lx < q.l)
            sub(A[lx++]);

        n = q.r - q.l;
        pref = 0, suff = 0;
        tmp = 0;

        for (int i = 0; i < idx;)
        {
            if (cnt[stuff[i]] == 0)
                swap(stuff[i], stuff[--idx]);
            else
                ++i;
        }
        sort(stuff, stuff + idx);

        for (int i = 0; i < idx; ++i)
        {
            ll x = stuff[i];
            if (i > 0 && stuff[i] == stuff[i - 1])
            {
                stuff[i] = N + 1;
                continue;
            }
            doStuff(x, (cnt[x] + 1) / 2);
            if (cnt[x] > 1)
            {
                doStuff(x, cnt[x] / 2);
                if (cnt[x] & 1)
                    swap(pref, suff);
            }
        }

        ans[q.idx] = tmp;
    }
    for (int i = 0; i < Q; ++i)
        cout << ans[i] << "\n";

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Incorrect 1 ms 340 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Incorrect 1 ms 340 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Incorrect 1 ms 340 KB Output isn't correct
4 Halted 0 ms 0 KB -