首页 > 代码库 > Vijos P1103 校门外的树【线段树,模拟】
Vijos P1103 校门外的树【线段树,模拟】
校门外的树
描述
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。 已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
格式
输入格式
输入的第一行有两个整数:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
输出格式
输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
样例1
样例输入1
500 3150 300100 200470 471
样例输出1
298
限制
每个测试点1s
来源
NOIP2005普及组第二题
题目链接:https://vijos.org/p/1103
思路:我估计也是智障了,这题明显可以用模拟做,我TM竟然用线段树写,还RE了两发,数组开了四倍你还要我怎样,结果我开了八倍过了QAQ!
下面给出线段树写法:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=20010; 4 int n,m,ans=1; 5 struct Node 6 { 7 int l,r,sum; 8 }tree[N<<2]; 9 inline void buildtree(int l,int r,int pos)10 {11 tree[pos].l=l;12 tree[pos].r=r;13 if(l==r)14 {15 tree[pos].sum=1;16 return;17 }18 int mid=(tree[pos].l+tree[pos].r)/2;19 buildtree(l,mid,pos*2);20 buildtree(mid+1,r,pos*2+1);21 tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;22 }23 inline int query(int l,int r,int pos)24 {25 if(tree[pos].l==l&&tree[pos].r==r)26 return tree[pos].sum;27 if(tree[pos].r<l||tree[pos].l>r)28 return 0;29 return query(l,r,pos*2)+query(l,r,pos*2+1);30 }31 inline void update(int l,int r,int pos)32 {33 if(tree[pos].l==l&&tree[pos].r==r)34 {35 tree[pos].sum=0;36 return;37 }38 if(tree[pos].l>r||tree[pos].r<l)39 return;40 update(l,r,pos*2);41 update(l,r,pos*2+1);42 tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;43 }44 int main()45 {46 cin>>n>>m;47 buildtree(1,n,1);48 for(int i=1;i<=m;i++)49 {50 int l,r;51 scanf("%d%d",&l,&r);52 if(!l)53 ans=0;54 update(!l?1:l,r,1);55 }56 cout<<query(1,n,1)+ans<<endl;57 return 0;58 }
模拟做法:简单解释一下,做法就是在【0,r】我们全部赋值为1,然后for一遍删去重复部分,非常简单,智障的我开始没想到,但是如果这题L的数据是1000000,线段树依然是正解!QAQ
下面给出模拟的代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=10010; 4 int a[N]; 5 int main() 6 { 7 int n,m; 8 cin>>n>>m; 9 for(int i=0;i<=n;i++)10 a[i]=1;11 for(int i=1;i<=m;i++)12 {13 int l,r;14 cin>>l>>r;15 for(int j=l;j<=r;j++)16 {17 a[j]=0;18 }19 }20 int sum=0;21 for(int i=0;i<=n;i++)22 {23 if(a[i])24 sum++;25 }26 cout<<sum<<endl;27 return 0;28 }
Vijos P1103 校门外的树【线段树,模拟】
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。