贪婪大陆

题目背景

面对蚂蚁们的疯狂进攻,小FF的Tower defence宣告失败……人类被蚂蚁们逼到了Greed Island上的一个海湾。现在,小FF的后方是一望无际的大海, 前方是变异了的超级蚂蚁。 小FF还有大好前程,他可不想命丧于此, 于是他派遣手下最后一批改造SCV布置地雷以阻挡蚂蚁们的进攻。

题目描述

小FF最后一道防线是一条长度为N的战壕, 小FF拥有无数多种地雷,而SCV每次可以在[ L , R ]区间埋放同一种不同于之前已经埋放的地雷。 由于情况已经十万火急,小FF在某些时候可能会询问你在[ L‘ , R‘] 区间内有多少种不同的地雷, 他希望你能尽快的给予答复。

对于30%的数据: 0<=n, m<=1000;

对于100%的数据: 0<=n, m<=10^5.

输入输出格式

输入格式:

第一行为两个整数n和m; n表示防线长度, m表示SCV布雷次数及小FF询问的次数总和。

接下来有m行, 每行三个整数Q,L , R; 若Q=1 则表示SCV在[ L , R ]这段区间布上一种地雷, 若Q=2则表示小FF询问当前[ L , R ]区间总共有多少种地雷。

输出格式:

对于小FF的每次询问,输出一个答案(单独一行),表示当前区间地雷总数。

输入输出样例

输入样例#1:

5 4
1 1 3
2 2 5
1 2 4
2 3 5

输出样例#1:

1
2
数状数组显而易见,同时线段树也可以解决,在这里用数状数组。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int N=100005;
int n,m;
int c[N],b[N];
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int v)
{
    for(int i=x;i<=n;i+=lowbit(i))
    c[i]+=v;
}
int getsum(int x)
{
    int sum=0;
    for(int i=x;i;i-=lowbit(i))
        sum+=c[i];
    return sum;
}
void add2(int x,int v)
{
    for(int i=x;i<=n;i+=lowbit(i))
    b[i]+=v;
}
int getsum2(int x)
{
    int sum=0;
    for(int i=x;i;i-=lowbit(i))
    sum+=b[i];
    return sum;
}
int main()
{
    int i,j,s,from,to;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&s,&from,&to);
        from++;to++;
        if(s==1)
        {
            add(from,1);
            add2(to,1);
        }
        if(s==2)
        {
            printf("%d\n",getsum(to)-getsum2(from-1));
        }
    }
    return 0;
}
时间: 2024-10-15 10:55:23

贪婪大陆的相关文章

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布置地雷以阻挡蚂蚁们的进攻. 

P2184 贪婪大陆

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

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

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

[luoguP2184] 贪婪大陆(树状数组)

传送门 用两个树状数组,cr 维护 1....x 中 r 的数量 cl 维护 1....x 中 l 的数量 求答案的时候只需要求 y 前面 被作为左端点 的个数 - x 前面 被作为右端点的个数 ——代码 1 #include <cstdio> 2 3 using namespace std; 4 5 const int MAXN = 1000001; 6 int n, m; 7 int cl[MAXN], cr[MAXN]; 8 9 inline void add1(int x) { for

cogs 1008 贪婪大陆

/* 不要思维定视 盯着线段树维护l r 的ans不放 显然没法区间合并 换一种思路 如果打暴力的话 O(nm) 每次询问 扫一遍之前所有的修改 有交点则说明种数++ 接下来考虑如何优化 我们把每个区间看做(l,r)的坐标内的点 然后查询区间L<=li<=R L<=ri<=R内有多少点 这样的查询在二维坐标里不会查(反正我不会..)将坐标轴转化成两个一维的线段 这样我们就又面临一个问题 会有重复 那就用排除法 总数-不重复区间的 又因为保证了 r>=l 所以l轴的[r+1,n

[洛谷P2184]贪婪大陆

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

luogu题解 P2184 【贪婪大陆】

题目链接: https://www.luogu.org/problemnew/show/P2184 思路: 首先我想吐槽一下为什么现有题解中的做法都是一样的,而且还比较难以理解; 我就讲下我的做法,本质上是一样的,但是跟容易理解. 根据题意每加一次地雷就多一个种类对吧,我们用一个cnt记录加过地雷的次数,同时分别用两个数组记录左右两个端点的位置.然后查询[l,r]时呢,我们分别查询[1,l-1]有多少个右端点,[r+1,n]有多少个左端点,然后这两个数的和是什么意思呢?就是有多少次铺地雷没铺到我