[洛谷P2184]贪婪大陆

题目大意:有n个点,每次在l~r之间所有点各加上同一种地雷,或询问某一区间内地雷种数。

解题思路:首先注意是“加上”而不是“覆盖”。

然后我们用两棵线段树(树状数组),一棵维护某一区间内左端点个数,另一棵维护右端点个数。

由于每次只加上一个端点,故为单点修改。

那么如何查询呢?

如果1~r内有a个左端点,则说明最多有a种地雷,如果1~l-1内有b个右端点,则说明a种地雷中,有b种的右端点没有达到l(否则一定在l-1之后)。

那么查询出a和b,然后输出a-b即可。

很明显是区间修改。

时间复杂度$O(m\log_2 n)$。

C++ Code:

#include<cstdio>
#include<cctype>
#include<cstring>
#define N 100005
int n,m,R,ans,d1[N<<2],d2[N<<2];
inline int readint(){
	char c=getchar();
	for(;!isdigit(c);c=getchar());
	int d=0;
	for(;isdigit(c);c=getchar())
	d=(d<<3)+(d<<1)+(c^‘0‘);
	return d;
}
void add1(int l,int r,int o){
	++d1[o];
	if(l!=r){
		int mid=l+r>>1;
		if(R<=mid)add1(l,mid,o<<1);
		if(mid<R)add1(mid+1,r,o<<1|1);
	}
}
void add2(int l,int r,int o){
	++d2[o];
	if(l!=r){
		int mid=l+r>>1;
		if(R<=mid)add2(l,mid,o<<1);
		if(mid<R)add2(mid+1,r,o<<1|1);
	}
}
void query1(int l,int r,int o){
	if(r<=R)ans+=d1[o];else{
		int mid=l+r>>1;
		query1(l,mid,o<<1);
		if(mid<R)query1(mid+1,r,o<<1|1);
	}
}
void query2(int l,int r,int o){
	if(r<=R)ans+=d2[o];else{
		int mid=l+r>>1;
		query2(l,mid,o<<1);
		if(mid<R)query2(mid+1,r,o<<1|1);
	}
}
int main(){
	n=readint(),m=readint();
	memset(d1,0,sizeof d1);
	memset(d2,0,sizeof d2);
	while(m--){
		int opt=readint(),l=readint(),r=readint();
		if(opt==1){
			R=l;
			add1(1,n,1);
			R=r;
			add2(1,n,1);
		}else{
			int Ans=0;
			ans=0;
			R=r;
			query1(1,n,1);
			Ans+=ans;
			ans=0;
			R=l-1;
			if(R)
			query2(1,n,1);
			Ans-=ans;
			printf("%d\n",Ans);
		}
	}
	return 0;
}
时间: 2024-08-01 12:32:31

[洛谷P2184]贪婪大陆的相关文章

P2184 贪婪大陆

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

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

洛谷 P1690 贪婪的Copy

P1690 贪婪的Copy 题目描述 Copy从卢牛那里听说在一片叫yz的神的领域埋藏着不少宝藏,于是Copy来到了这个被划分为个区域的神地.卢牛告诉了Copy这里共有个宝藏,分别放在第Pi个(1<=Pi<=N)区域.Copy还得知了每个区域之间的距离.现在Copy从1号区域出发,要获得所有的宝藏并到n号区域离开.Copy很懒,只好来找你为他寻找一条合适的线路,使得他走过的距离最短. 输入输出格式 输入格式: 第一行一个正整数N(1<=N<=100) 接下来一个N*N的矩阵,第i+

洛谷——P1690 贪婪的Copy

P1690 贪婪的Copy 题目描述 Copy从卢牛那里听说在一片叫yz的神的领域埋藏着不少宝藏,于是Copy来到了这个被划分为个区域的神地.卢牛告诉了Copy这里共有个宝藏,分别放在第Pi个(1<=Pi<=N)区域.Copy还得知了每个区域之间的距离.现在Copy从1号区域出发,要获得所有的宝藏并到n号区域离开.Copy很懒,只好来找你为他寻找一条合适的线路,使得他走过的距离最短. 输入输出格式 输入格式: 第一行一个正整数N(1<=N<=100) 接下来一个N*N的矩阵,第i+

洛谷—— P1690 贪婪的Copy

https://www.luogu.org/problem/show?pid=1690 题目描述 Copy从卢牛那里听说在一片叫yz的神的领域埋藏着不少宝藏,于是Copy来到了这个被划分为个区域的神地.卢牛告诉了Copy这里共有个宝藏,分别放在第Pi个(1<=Pi<=N)区域.Copy还得知了每个区域之间的距离.现在Copy从1号区域出发,要获得所有的宝藏并到n号区域离开.Copy很懒,只好来找你为他寻找一条合适的线路,使得他走过的距离最短. 输入输出格式 输入格式: 第一行一个正整数N(1&

Luogu P2184 贪婪大陆

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

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

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

洛谷 P1736 创意吃鱼法

题目描述 题目链接:https://www.luogu.org/problemnew/show/P1736 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略. 在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵"对角线的一端

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3