QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#426828#964. Excluded MinEstelle_NWA 5ms26400kbC++144.7kb2024-05-31 22:24:232024-05-31 22:24:24

Judging History

你现在查看的是最新测评结果

  • [2024-05-31 22:24:24]
  • 评测
  • 测评结果:WA
  • 用时:5ms
  • 内存:26400kb
  • [2024-05-31 22:24:23]
  • 提交

answer

#include <set>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 500005;

int n, m, a[N], c[N], ans[N];
vector <int> p[N];

struct Query
{
    int l, r, id;
};
Query q[N];

struct SegmentTree
{
    struct Node
    {
        int Max, pos;
    };
    struct Tree
    {
        int l, r, Max, pos, add;
    };
    Tree s[N << 2];

    #define ls p << 1
    #define rs p << 1 | 1

    void build(int p, int l, int r)
    {
        s[p].l = l;
        s[p].r = r;
        s[p].pos = l;
        if(l == r)
            return;
        int mid = l + r >> 1;
        build(ls, l, mid);
        build(rs, mid + 1, r);
    }

    void push_down(int p)
    {
        s[ls].add += s[p].add;
        s[ls].Max += s[p].add;
        s[rs].add += s[p].add;
        s[rs].Max += s[p].add;
        s[p].add = 0;
    }

    void push_up(int p)
    {
        s[p].Max = max(s[ls].Max, s[rs].Max);
        if(s[ls].Max >= s[rs].Max)
            s[p].pos = s[ls].pos;
        else
            s[p].pos = s[rs].pos;
    }

    void Add(int p, int l, int r, int k)
    {
        if(s[p].l >= l && s[p].r <= r)
        {
            s[p].add += k;
            s[p].Max += k;
            return;
        }
        push_down(p);
        int mid = s[p].l + s[p].r >> 1;
        if(l <= mid)
            Add(ls, l, r, k);
        if(r > mid)
            Add(rs, l, r, k);
        push_up(p);
    }

    void Upd(int p, int x, int k)
    {
        if(s[p].l == s[p].r)
        {
            s[p].Max = k;
            return;
        }
        push_down(p);
        int mid = s[p].l + s[p].r >> 1;
        if(x <= mid)
            Upd(ls, x, k);
        else
            Upd(rs, x, k);
        push_up(p);
    }

    Node maxNode(Node x, Node y)
    {
        if(x.Max >= y.Max)
            return x;
        return y;
    }

    Node Get(int p, int l, int r)
    {
        if(s[p].l >= l && s[p].r <= r)
            return (Node){s[p].Max, s[p].pos};
        push_down(p);
        int mid = s[p].l + s[p].r >> 1;
        if(r <= mid)
            return Get(ls, l, r);
        if(l > mid)
            return Get(rs, l, r);
        return maxNode(Get(ls, l, r), Get(rs, l, r));
    }
};
SegmentTree S, T;

set < pair<int, int> > lpos, rpos;

void add(int x, int k)
{
    for(; x <= n; x += x & -x)
        c[x] += k;
}

int get(int x)
{
    int r = 0;
    for(; x; x -= x & -x)
        r += c[x];
    return r;
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++ i)
        scanf("%d", &a[i]), p[a[i]].push_back(i), add(i, 1);
    for(int i = 1; i <= m; ++ i)
        scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;

    sort(q + 1, q + 1 + m, [](Query i, Query j)
        { return i.l == j.l ? i.r > j.r : i.l < j.l;});

    T.build(1, 1, m);
    S.build(1, 1, m);
    for(int i = 1, R = 0; i <= m; ++ i)
    {
        if(q[i].l == q[i - 1].l || q[i].r <= R)
        {
            S.Upd(1, i, q[i].r);
            T.Upd(1, i, -1e9);
        }
        else
        {
            R = q[i].r;
            T.Upd(1, i, q[i].r - q[i].l + 1);
            lpos.insert(make_pair(q[i].l, i));
            rpos.insert(make_pair(q[i].r, i));
        }    
    }

    for(int i = n; i >= 0; -- i)
    {
        for(int u : p[i])
        {
            add(u, -1);
            auto itl = lpos.upper_bound(make_pair(u, N));
            auto itr = rpos.lower_bound(make_pair(u, 0));
            // printf("{%d, %d}, {%d, %d}\n", itl -> first, itl -> second, itr -> first, itr -> second);
            if(itl != lpos.begin() && itr != rpos.end() && prev(itl) -> second <= itr -> second)
                T.Add(1, prev(itl) -> second, itr -> second, -1);
        }
        while(T.s[1].Max >= i)
        {
            int u = T.s[1].pos, x;
            ans[q[u].id] = i;
            auto itr = lpos.upper_bound(make_pair(q[u].l, u));
            int r = (itr == lpos.end() ? m : itr -> second);
            int R = (itr == lpos.begin() ? 0 : prev(itr) -> first);
            if(itr == lpos.end() && prev(itr) -> second == u)
                R = 0;

            while(u + 1 <= r && q[x = S.Get(1, u + 1, r).pos].r > R)
            {
                R = q[x].r;
                lpos.insert(make_pair(q[x].l, x));
                rpos.insert(make_pair(q[x].r, x));
                S.Upd(1, x, 0);
                T.Upd(1, x, get(q[x].r) - get(q[x].l - 1));
            }
            
            lpos.erase(make_pair(q[u].l, u));
            rpos.erase(make_pair(q[u].r, u));
            T.Upd(1, u, -1e9);
        }
    }

    for(int i = 1; i <= m; ++ i)
        printf("%d\n", ans[i]);

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 5ms
memory: 24292kb

input:

3 3
0 0 2
1 3
2 3
3 3

output:

3
1
0

result:

ok 3 number(s): "3 1 0"

Test #2:

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

input:

3 2
1 2 2
1 2
1 3

output:

0
3

result:

ok 2 number(s): "0 3"

Test #3:

score: -100
Wrong Answer
time: 5ms
memory: 26400kb

input:

10 10
3 0 3 3 9 7 9 6 0 7
3 3
9 9
4 6
1 9
3 4
2 4
7 10
3 7
5 7
2 7

output:

0
0
0
8
0
0
0
0
0
1

result:

wrong answer 2nd numbers differ - expected: '1', found: '0'