Luogu P2184 贪婪大陆

题目

Luogu P2184

维护一个 \(n\) 项的序列,有 \(m\) 个操作,为以下两种之一:

  • 1 l r 表示在 \([l,r]\) 这段区间布上一种地雷
  • 2 l r 表示询问 \([l,r]\) 区间内共有多少种地雷

分析

可以把区间的左端点和右端点分开处理:如果某种地雷在 \([l,r]\) 内存在,那么这种地雷的左端点一定小于等于 \(r\) ,且右端点一定大于等于 \(l\) ,所以答案就是小于等于 \(r\) 的左端点数减去小于 \(l\) 的右端点数

代码

#include<bits/stdc++.h>
#define ls(k) k << 1
#define rs(k) k << 1 | 1
using namespace std;

const int MAX_N = 100000 + 5;
int sum1[MAX_N * 4], sum2[MAX_N * 4];

void modify1(int k, int l, int r, int x, int v)
{
    if(l == r && l == x) {
        sum1[k] += v;
        return;
    }
    int m = (l + r) >> 1;
    if(x <= m)
        modify1(ls(k), l, m, x, v);
    else
        modify1(rs(k), m + 1, r, x, v);
    sum1[k] = sum1[ls(k)] + sum1[rs(k)];
}

void modify2(int k, int l, int r, int x, int v)
{
    if(l == r && l == x) {
        sum2[k] += v;
        return;
    }
    int m = (l + r) >> 1;
    if(x <= m)
        modify2(ls(k), l, m, x, v);
    else
        modify2(rs(k), m + 1, r, x, v);
    sum2[k] = sum2[ls(k)] + sum2[rs(k)];
}

int query1(int k, int l, int r, int x, int y)
{
    if(l >= x && r <= y)
        return sum1[k];
    int m = (l + r) >> 1;
    int res = 0;
    if(x <= m)
        res += query1(ls(k), l, m, x, y);
    if(m + 1 <= y)
        res += query1(rs(k), m + 1, r, x, y);
    return res;
}

int query2(int k, int l, int r, int x, int y)
{
    if(l >= x && r <= y)
        return sum2[k];
    int m = (l + r) >> 1;
    int res = 0;
    if(x <= m)
        res += query2(ls(k), l, m, x, y);
    if(m + 1 <= y)
        res += query2(rs(k), m + 1, r, x, y);
    return res;
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    while(m--) {
        int q, l, r;
        scanf("%d%d%d", &q, &l, &r);
        if(q == 1) {
            modify1(1, 1, n, l, 1);
            modify2(1, 1, n, r, 1);
        } else {
            if(l == 1)
                printf("%d\n", query1(1, 1, n, 1, r));
            else
                printf("%d\n", query1(1, 1, n, 1, r) - query2(1, 1, n, 1, l - 1));
        }
    }
    return 0;
}
posted @ 2022-01-21 23:20  f(k(t))  阅读(33)  评论(0编辑  收藏  举报