四重解法---P1047 校门外的树
题目描述
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入输出格式
输入格式:
输入文件tree.in的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
输出格式:
输出文件tree.out包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
输入输出样例
输入样例#1:
500 3
150 300
100 200
470 471
输出样例#1:
298
说明
NOIP2005普及组第二题
对于20%的数据,区域之间没有重合的部分;
对于其它的数据,区域之间有重合的情况。
分析
四种解法,不解释
#include<bits/stdc++.h> //1层----模拟流
using namespace std;
int n,m,ans;
bool a[11000];
int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c) && c!='-') c=getchar();
if(c=='-') f=-1,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*f;
}
int main()
{
n=read()+1;m=read();
while(m--)
{
int l=read(),r=read();
for(int i=l;i<=r;++i)
a[i]=1; //表示已被砍
}
for(int i=0;i<=n;++i)
if(a[i]) ++ans;
printf("%d\n",n-ans);
return 0;
}
这里是分割线
#include<bits/stdc++.h> //2层----忘了是什么算法来着,反正比模拟高级
using namespace std;
int n,m,ans;
int a[11000],f[11000];
int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c) && c!='-') c=getchar();
if(c=='-') f=-1,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*f;
}
int main()
{
n=read()+1;m=read(); //代码需要,就+1了,下同
while(m--)
{
int l=read()+1,r=read()+1;
++a[l];--a[r+1];
}
for(int i=1;i<=n;++i)
{
f[i]=f[i-1]+a[i];
if(f[i]) ++ans; //被砍过,ans++
}
printf("%d\n",n-ans);
return 0;
}
这里是分割线
#include<bits/stdc++.h> //3层----树状数组(比线段树好打一些)
using namespace std;
int n,m,f[11000],ans;
/* 本代码以树状数组区间加,单点查询为模板 */
int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c) && c!='-') c=getchar();
if(c=='-') f=-1,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*f;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int i,int x)
{
for(;i<=n;i+=lowbit(i))
f[i]+=x;
}
bool query(int i)
{
int res=0;
for(;i;i-=lowbit(i))
if(f[i]) res+=f[i];
return res;
}
int main()
{
n=read()+1;m=read(); //注意题目中的树范围是0~n,
//树状数组的操作是从1开始的,所以n++
while(m--)
{
int l=read()+1,r=read()+1; //同上+1
update(l,1);
update(r+1,-1);
}
for(int i=1;i<=n;++i)
if(query(i)) ++ans; //被砍过,ans++
printf("%d\n",n-ans);
return 0;
}
这里是分割线
#include<bits/stdc++.h> //4层----线段树
using namespace std;
int n,m,sum[41000];
//姑且写个读入优化吧,虽说其实用不着
int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c) && c!='-') c=getchar();
if(c=='-') f=-1,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*f;
}
void buildtree(int k,int l,int r)
{
if(l==r){ sum[k]=1; return ;}
if(l>r) return ;
int mid=l+r>>1;
buildtree(k*2,l,mid);
buildtree(k*2+1,mid+1,r);
sum[k]=sum[k*2]+sum[k*2+1];
}
void update(int k,int l,int r,int L,int R)
{
if(l>R || r<L || !sum[k]) return ; //不包含直接退
if(L<=l && r<=R) //全包含sum改0
{
sum[k]=0;
return ;
}
int mid=l+r>>1;
update(k*2,l,mid,L,R);
update(k*2+1,mid+1,r,L,R);
sum[k]=sum[k*2]+sum[k*2+1]; //更新sum[father];
}
int main()
{
n=read();m=read();
buildtree(1,0,n);
while(m--)
{
int l,r;
l=read();r=read();
update(1,0,n,l,r);
}
printf("%d\n",sum[1]);
return 0;
}
--all by Mr Zhang
ok,四种解法发完。
(你会几种?_ (:зゝ∠) _)
测试平台
四重解法---P1047 校门外的树的更多相关文章
- P1047 校门外的树
P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...
- 洛谷P1047 校门外的树
P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...
- 洛谷——P1047 校门外的树
P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...
- luogu P1047 校门外的树 x
P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...
- 【洛谷】【线段树】P1047 校门外的树
[题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...
- [模拟]P1047 校门外的树
校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,- ...
- 洛谷 P1047 校门外的树(待完善)
链接:https://www.luogu.org/problemnew/show/P1047 题目: 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是11米.我们可以把马路看 ...
- 洛谷题解P1047 校门外的树
题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,…,L,都种有 ...
- [线段树]P1047 校门外的树
题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种 ...
随机推荐
- python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...
- C#设计模式(6)——原型模式
1.原型模式介绍 在软件系统开发中,有时候会遇到这样的情况:我们需要用到多个相同实例,最简单直接的方法是通过多次调用new方法来创建相同的实例.如下: Person person=}; Person ...
- c/c++gdb下和发布版本下输出地址不同
相差4字节 相差8个字节 原因: 这4个字节是优化掉了,64位操作系统,函数传参通过寄存器,减少了栈的使用 debug模式下,abc的地址都存下来了.
- c++后台开发路线
- Silverlight数据绑定之 绑定一个int类型的属性
还就真心不会啊! 在类FunctionPanel中作如下定义: /// <summary> /// 鼠标状态 属性 /// </summary> public Dependen ...
- Java入门系列
包装类 基本数据类型之间的相互转换不是都可以制动转换的,而你强制转换又会出问题,比如String类型的转换为int类型的,那么jdk为了方便用户就提供了相应的包装类. 基本类型对应的包装类 创建一个包 ...
- Groovy的脚本统一于类的世界
http://groovy-lang.org/structure.html 3.2. Script class A script is always compiled into a class. Th ...
- Javaweb学习笔记——(十七)——————JDBC的原理、四大核心类、四大参数、预编译、Dao模式、批处理、大数据、时间类型的转换
JDBC入门 *导入jar包:驱动 *加载驱动类:Class.forName("类名"); *给出url.username.password,其中url背下来 *使用DriverM ...
- Linux 下磁盘挂载
Linux 磁盘挂载 新硬盘挂载: fdisk /dev/sdb p # 打印分区 d # 删除分区 n # 创建分区,(一块硬盘最多4个主分区,扩展占一个主分区位置.p主分区 e扩展) w # 保存 ...
- Scala思维导图