vijos P1448 校门外的树

描述

校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,K=1,读入l、r表示在区间[l,r]中种上一种树,每次操作种的树的种类都不同
K=2,读入l,r表示询问l~r之间能见到多少种树(l,r>0)

输入格式

第一行n,m表示道路总长为n,共有m个操作
接下来m行为m个操作

输出格式

对于每个k=2输出一个答案

提示

范围:20%的数据保证,n,m<=100
60%的数据保证,n <=1000,m<=50000
100%的数据保证,n,m<=50000

  由于这两天BZOJ炸了,于是准备上vijos刷点题……然后发现刷不动……我好弱啊……

  由于这道题想了半天不会做,被嘲讽数据结构学傻了……好吧,这几天我整天整天的不在状态

  好吧,我还是来讲一下写法(其实这道题的在vijos上就有非常详细的讲解了)。这道题目大意就是给出一些区间,每次询问一个区间和多少个区间有交。

  然后,一个区间和另一个区间有交,当且仅当那个区间的左端点或者右端点在这个区间里。于是,我们就可以令ai表示前i个点共出现了多少个区间左端点,bi表示出现了多少个右端点。这两个东西用树状数组维护即可。询问区间[l,r]的答案就是ar-bl-1

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 50010

using namespace std;
typedef long long llg;

int c1[maxn],c2[maxn];
int n,m;

int getint(){
	int w=0;bool q=0;
	char c=getchar();
	while((c>‘9‘||c<‘0‘)&&c!=‘-‘) c=getchar();
	if(c==‘-‘) c=getchar(),q=1;
	while(c>=‘0‘&&c<=‘9‘) w=w*10+c-‘0‘,c=getchar();
	return q?-w:w;
}

void add1(int x,int y){while(x<=n) c1[x]+=y,x+=x&(-x);}
void add2(int x,int y){while(x<=n) c2[x]+=y,x+=x&(-x);}
int sum1(int x){
	int t=0;
	while(x) t+=c1[x],x-=x&(-x);
	return t;
}
int sum2(int x){
	int t=0;
	while(x) t+=c2[x],x-=x&(-x);
	return t;
}

int main(){
	File("a");
	n=getint(); m=getint();
	while(m--){
		int ty=getint(),l,r;
		l=getint();r=getint();
		if(ty==1) add1(l,1),add2(r,1);
		else printf("%d\n",sum1(r)-sum2(l-1));
	}
}
时间: 2024-12-29 02:50:39

vijos P1448 校门外的树的相关文章

Vijos P1448 校门外的树【多解,线段树,树状数组,括号序列法+暴力优化】

校门外的树 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,K=1,读入l.r表示在区间[l,r]中种上一种树,每次操作种的树的种类都不同 K=2,读入l,r表示询问l~r之间能见到多少种树 (l,r>0) 格式 输入格式 第一行n,m表示道路总长为n,共有m个操作 接下来m行为m个操作 输出格式 对于每个k=2输出一个答案 样例1 样例输入1 5 4 1 1

Vijos P1103 校门外的树【线段树,模拟】

校门外的树 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示. 已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上还有多少棵树. 格式 输入格式 输入的

【vijos】P1448 校门外的树

[算法]树状数组||线段树 [题解]括号法,对于每个K=1的操作标记左右括号的位置,即在left和right的位置分别+1(不同标记). 对于每个K=2的操作,答案就是right前面的左括号数量-(left-1)前面的右括号数量. 用树状数组或线段树优化. 注意数组在传递给函数时是传递地址,即在函数中修改即相当于修改原数组. 线段树: #include<cstdio> const int maxn=50010; struct treess{int l,r,sum[3];}t[maxn*3];

一本通1537校门外的树

1537:[例 3]校门外的树 时间限制: 1000 ms         内存限制: 524288 KB [题目描述] 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两种操作: K=1K=1,读入 l,rl,r 表示在 ll 到 rr 之间种上一种树,每次操作种的树的种类都不同: K=2K=2,读入 l,rl,r 表示询问 ll 到 rr 之间有多少种树. 注意:每个位置都可以重复种树. [输入] 第一行 n,

#10115 「一本通 4.1 例 3」校门外的树

1537:[例 3]校门外的树 时间限制: 1000 ms         内存限制: 524288 KB提交数: 497     通过数: 216 [题目描述] 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两种操作: K=1K=1,读入 l,rl,r 表示在 ll 到 rr 之间种上一种树,每次操作种的树的种类都不同: K=2K=2,读入 l,rl,r 表示询问 ll 到 rr 之间有多少种树. 注意:每个位

Vijos1448校门外的树 题解

Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,K=1,读入l.r表示在区间[l,r]中种上一种树,每次操作种的树的种类都不同 K=2,读入l,r表示询问l~r之间能见到多少种树 (l,r>0) 输入格式: 第一行n,m表示道路总长为n,共有m个操作 接下来m行为m个操作 输出格式: 对于每个k=2输出一个答案 样例输入:

C语言 &#183; 校门外的树

算法提高 校门外的树 时间限制:1.0s   内存限制:256.0MB 问题描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,--,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示.已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算

P1047 校门外的树

P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示.已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上还有多少棵树. 输入输出

TyvjOJ题目 P1473 校门外的树3(线段树区间染色种类数不覆盖)

P1473 校门外的树3 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的-- 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,读入l,r表示在l~r之间种上的一种树 K=2,读入l,r表示询问l~r之间能见到多少种树 (l,r>0) 输入格式 第一行n,m表示道路总长为n,共有m个操作 接下来m行为m个操作 输出格式 对于每个k=