luogu题解 P2184 【贪婪大陆】

  • 题目链接:

https://www.luogu.org/problemnew/show/P2184

  • 思路:

首先我想吐槽一下为什么现有题解中的做法都是一样的,而且还比较难以理解;

我就讲下我的做法,本质上是一样的,但是跟容易理解.

根据题意每加一次地雷就多一个种类对吧,我们用一个cnt记录加过地雷的次数,同时分别用两个数组记录左右两个端点的位置。然后查询[l,r]时呢,我们分别查询[1,l-1]有多少个右端点,[r+1,n]有多少个左端点,然后这两个数的和是什么意思呢?就是有多少次铺地雷没铺到我们查询的这个[l,r]区间。

最后cnt-刚刚两次查询的和就是有多少次地雷铺到了[l,r]这个区间,输出即可,当然,我们用线段树维护这些操作。

  • 代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cctype>
using namespace std;
const int maxn=100005;
int sum_r[maxn<<2],sum_l[maxn<<2],add[maxn<<2];
int n,m;
int L,R;
void update_l(int now,int l,int r,int t){
    if(l==r){
        sum_l[now]++;
        return ;
    }
    int mid=(l+r)>>1;
    if(t<=mid)update_l(now<<1,l,mid,t);
    else update_l(now<<1|1,mid+1,r,t);
    sum_l[now]=sum_l[now<<1]+sum_l[now<<1|1];
    return ;
}
void update_r(int now,int l,int r,int t){
    if(l==r){
        sum_r[now]++;
        return ;
    }
    int mid=(l+r)>>1;
    if(t<=mid)update_r(now<<1,l,mid,t);
    else update_r(now<<1|1,mid+1,r,t);
    sum_r[now]=sum_r[now<<1]+sum_r[now<<1|1];
    return ;
}
int query_l(int now,int l,int r){
    if(L<=l&&r<=R){
        return sum_l[now];
    }
    int mid=(l+r)>>1;
    int ans=0;
    if(L<=mid)ans+=query_l(now<<1,l,mid);
    if(mid<R)ans+=query_l(now<<1|1,mid+1,r);
    return ans;
}
int query_r(int now,int l,int r){
    if(L<=l&&r<=R){
        return sum_r[now];
    }
    int mid=(l+r)>>1;
    int ans=0;
    if(L<=mid)ans+=query_r(now<<1,l,mid);
    if(mid<R)ans+=query_r(now<<1|1,mid+1,r);
    return ans;
}
int main()
{
    int op,l,r;
    int cnt=0,tmp=0;
    scanf("%d %d",&n,&m);
    for(register int i=1;i<=m;i++){
        scanf("%d %d %d",&op,&l,&r);
        if(op==1){
            update_l(1,1,n,l);
            update_r(1,1,n,r);
            cnt++;
        }
        else {
            L=r+1,R=n;
            if(L<=R)tmp+=query_l(1,1,n);
            L=1,R=l-1;
            if(L<=R)tmp+=query_r(1,1,n);
            cout<<cnt-tmp<<endl;
            tmp=0;
        }
    }
    return 0;
} 

原文地址:https://www.cnblogs.com/Rye-Catcher/p/8964126.html

时间: 2024-08-01 12:32:24

luogu题解 P2184 【贪婪大陆】的相关文章

P2184 贪婪大陆

P2184 贪婪大陆 题目背景 面对蚂蚁们的疯狂进攻,小FF的Tower defence宣告失败……人类被蚂蚁们逼到了Greed Island上的一个海湾.现在,小FF的后方是一望无际的大海, 前方是变异了的超级蚂蚁. 小FF还有大好前程,他可不想命丧于此, 于是他派遣手下最后一批改造SCV布置地雷以阻挡蚂蚁们的进攻. 题目描述 小FF最后一道防线是一条长度为N的战壕, 小FF拥有无数多种地雷,而SCV每次可以在[ L , R ]区间埋放同一种不同于之前已经埋放的地雷. 由于情况已经十万火急,小

Luogu P2184 贪婪大陆

线段树 我居然想了一个半小时才想出来 读完题可以发现如果布不同地雷的区间如果相交的话,地雷是不会覆盖的 两种不同的地雷会共存在一格中 那么在问题可以转化,所求答案就是当前询问的区间与之前布地雷的区间有多少个相交或包含 (我没想到) 那么考虑一个区间不与另一个区间相交的条件 即$r_{1}<l_{2}$或$l_{1}>r_{2}$ 那么可以用线段树维护对于每个点区间右端点小于等于这点的区间数量$s1$,和左端点大于等于这点的区间数量$s2$ 那么询问时答案就是当前布地雷的总数量减去$s1[l-1

[洛谷P2184]贪婪大陆

题目大意:有n个点,每次在l~r之间所有点各加上同一种地雷,或询问某一区间内地雷种数. 解题思路:首先注意是“加上”而不是“覆盖”. 然后我们用两棵线段树(树状数组),一棵维护某一区间内左端点个数,另一棵维护右端点个数. 由于每次只加上一个端点,故为单点修改. 那么如何查询呢? 如果1~r内有a个左端点,则说明最多有a种地雷,如果1~l-1内有b个右端点,则说明a种地雷中,有b种的右端点没有达到l(否则一定在l-1之后). 那么查询出a和b,然后输出a-b即可. 很明显是区间修改. 时间复杂度$

【题解】贪婪大陆

线段树差分经典题. 题目链接 解: 对于题目中要求的维护区间颜色种数,暴力维护必定不可取.于是,我们考虑线段树的性质:从下向上维护左右区间信息. 那么,我们可不可以利用这一点来简单维护它的颜色种类数呢? 我们可以维护一组地雷(颜色)的开头和结尾. 显然,我们这样可以任意求出任意区间的开头数和结尾数.那么,复杂的区间修改就变成了单点修改. 注意线段树的性质,也就是说,即使它的开头不在询问区间,只要它覆盖了,就一定不会遗漏. 那么,套用差分公式,r-l+1,即 query_s(1,r,1)-quer

luoguP2184 贪婪大陆 题解(树状数组)

P2184 贪婪大陆  题目 其实很容易理解就是询问一段区间内有多少段不同的区间 然后再仔细思索一下会发现: 1.只要一个区间的开头在一个节点i的左边,那么这个区间包含在区间1~i中. 2.只要一个区间的尾部在一个节点j的左边,那么这个区间肯定不属于j之后的所有区间 这时候就不难想到用两个树状数组维护: 第一个:维护节点i之前有多少个区间的开头 第二个:维护节点j之前有多少个区间的结尾 不难证明拿sum[i]-sum[j]得到的就是i~j中间地雷的个数(手动模拟一波就一清二楚了) #includ

AC日记——贪婪大陆 洛谷 P2184

贪婪大陆 思路: 树状数组: 跪烂.. 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 int n,m,ltree[maxn],rtree[maxn],tot; inline void in(int &now) { char Cget=getchar();now=0; while(Cget>'9'||Cget<'0')Cget=getchar(); while(Cget>='0

cogs——1008. 贪婪大陆(清华巨佬代码)——树状数组

1008. 贪婪大陆 ★★   输入文件:greedisland.in   输出文件:greedisland.out   简单对比时间限制:1 s   内存限制:128 MB 试题四:贪婪大陆  [题目描述]  面对蚂蚁们的疯狂进攻,小FF的Tower defense宣告失败……人类被蚂蚁们逼到了Greed Island上的一个海湾.现在,小FF的后方是一望无际的大海,前方是变异了的超级蚂蚁. 小FF还有大好前程,他可不想命丧于此, 于是他派遣手下最后一批改造SCV布置地雷以阻挡蚂蚁们的进攻. 

COGS1008. 贪婪大陆[树状数组 模型转换]

1008. 贪婪大陆 ★★   输入文件:greedisland.in   输出文件:greedisland.out   简单对比时间限制:1 s   内存限制:128 MB 试题四:贪婪大陆  [题目描述]  面对蚂蚁们的疯狂进攻,小FF的Tower defense宣告失败……人类被蚂蚁们逼到了Greed Island上的一个海湾.现在,小FF的后方是一望无际的大海,前方是变异了的超级蚂蚁. 小FF还有大好前程,他可不想命丧于此, 于是他派遣手下最后一批改造SCV布置地雷以阻挡蚂蚁们的进攻. 

【LuoGu题解】 P1362 【兔子数】

依题意模拟暴力打表找规律,注意到:符合题意的数中只包含\(0,1,2,3\),大于\(3\)的数,平方后都会进位,进位导致\(S(x)*S(x)<S(x*x)\) 观察数据范围,最大满足题意的数字有\(10\)位,那么我们枚举每一位上的数字,然后暴力判断是否为兔子数就行了. Code: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #inclu