校门外的树 Plus Plus(0764)

问题描述

西南某科技大学的校门外长度为 L 的公路上有一排树,每两棵相邻的树之间的间隔都是 1 米。我们可以把马路看成一个数轴,马路的一端在数轴 1 的位置,另一端在 L 的位置;数轴上的每个整数点,即 1,2,……,L,都种有一棵树。

现在要将这排树的某一段涂成某种颜色,给定 N 组区间[ J,K ],表示从 J 到 K 的树都要涂上一种颜色(每次涂的颜色不一样,而且每次涂色会覆盖掉原来的颜色),区间之间可能有重叠的部分, L 的长度为 1000,0000。现在你的任务是计算涂色工作结束后,这一排树里总共有多少种颜色的树?(没涂过色的不算)

输入

第一行为一个整数N (1<=N<=10000)。 接下来的N行每行是两个整数数J,K(1<=J<=K<=1000,0000),表示涂色的起止区间。

多组测试数据。

输出

一个整数,表示有多少种颜色的树。

样例输入

2
1 10
5 5
1
1 1

样例输出

2
1
 
线段树可解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 40005 struct tree
{
int l,r;
}p[N<<]; int tot;
int ans;
int x[N];
int lazy[N<<];
bool flag[N<<]; void pushdown(int rt)
{
if(lazy[rt]!=-)
{
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
lazy[rt]=-;
}
}
void build(int l,int r,int rt)
{
lazy[rt]=-;
if(l==r) return;
int m=(l+r)>>;
build(l,m,rt<<);
build(m+,r,rt<<|);
}
void update(int l,int r,int rt,int L,int R,int c)
{
if(l==L && R==r)
{
lazy[rt]=c;
return;
}
pushdown(rt);
int m=(l+r)>>;
if(R<=m) update(l,m,rt<<,L,R,c);
else if(L>m) update(m+,r,rt<<|,L,R,c);
else
{
update(l,m,rt<<,L,m,c);
update(m+,r,rt<<|,m+,R,c);
}
}
void query(int l,int r,int rt)
{
if(lazy[rt]!=-)
{
if(!flag[lazy[rt]])
{
ans++;
flag[lazy[rt]]=;
}
return;
}
if(l>=r) return;
pushdown(rt);
int m=(l+r)>>;
query(l,m,rt<<);
query(m+,r,rt<<|);
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
ans=;
tot=;
memset(flag,,sizeof(flag));
for(i=;i<n;i++)
{
scanf("%d%d",&p[i].l,&p[i].r);
x[tot++]=p[i].l;
x[tot++]=p[i].r;
} sort(x,x+tot);
tot=unique(x,x+tot)-x;
for(i=tot-;i>;i--)
{
if(x[i]-x[i-]>) x[tot++]=x[i-]+;
}
sort(x,x+tot);
build(,tot-,);
for(i=;i<n;i++)
{
int l=lower_bound(x,x+tot,p[i].l)-x;
int r=lower_bound(x,x+tot,p[i].r)-x;
update(,tot-,,l,r,i);
}
query(,tot-,);
cout<<ans<<endl;
}
return ;
}

原来搓代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 20005 struct tree
{
int l,r;
}p[N<<];
struct node
{
int val,id,pos;
}h[N<<]; int ans;
int color[N<<];
bool flag[N<<];
int change[N<<]; bool cmp(node a,node b)
{
return a.val<b.val;
}
void pushup(int rt)
{
color[rt]=;
}
void pushdown(int rt)
{
if(change[rt]!=-)
{
change[rt<<]=change[rt<<|]=change[rt];
color[rt<<]=color[rt<<|]=change[rt];
change[rt]=-;
}
}
void build(int l,int r,int rt)
{
color[rt]=;
change[rt]=-;//初始化
if(l==r) return;
int m=(l+r)>>;
build(l,m,rt<<);
build(m+,r,rt<<|);
}
void update(int l,int r,int rt,int L,int R,int c)
{
if(l==L && R==r)
{
color[rt]=c;
change[rt]=c;
return;
}
pushdown(rt);
int m=(l+r)>>;
if(R<=m)
update(l,m,rt<<,L,R,c);
else if(L>m)
update(m+,r,rt<<|,L,R,c);
else
{
update(l,m,rt<<,L,m,c);
update(m+,r,rt<<|,m+,R,c);
}
pushup(rt);
}
void query(int l,int r,int rt)
{
int m=(l+r)>>;
if(color[rt])
{
if(!flag[color[rt]])
{
ans++;
flag[color[rt]]=;
}
return;
}
if(l==r) return; //忘了加这一句、一直RE
query(l,m,rt<<);
query(m+,r,rt<<|);
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
ans=;
memset(flag,,sizeof(flag));
for(i=;i<n;i++)
{
scanf("%d%d",&p[i].l,&p[i].r);
h[i*].val=p[i].l;
h[i*].id=i;
h[i*].pos=;
h[i*+].val=p[i].r;
h[i*+].id=i;
h[i*+].pos=;
}
/* 离散化 */
sort(h,h+n*,cmp);
int last=-,total=;
for(i=;i<n*;i++)
{
if(h[i].val!=last)
{
total++;
if(i && h[i].val-h[i-].val>) total++; //注意这里、= =、手动插点
last=h[i].val;
}
if(h[i].val!=total)
{
if(h[i].pos) p[h[i].id].r=total;
else p[h[i].id].l=total;
}
}
build(,total,);
for(i=;i<n;i++)
{
update(,total,,p[i].l,p[i].r,i+);
}
query(,total,);
cout<<ans<<endl;
}
return ;
}

[swustoj 764] 校门外的树 Plus Plus的更多相关文章

  1. P1047 校门外的树

    P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...

  2. Vijos1448校门外的树 题解

    Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...

  3. OpenJudge计算概论-校门外的树

    /*======================================================================== 校门外的树 总时间限制: 1000ms 内存限制: ...

  4. 校门外的树 - Grids2808

    校门外的树 问题描述: 某校大门外长度为 L 的马路上有一排树,每两棵相邻的树之间的间隔都是1 米.我们 可以把马路看成一个数轴,马路的一端在数轴0 的位置,另一端在L 的位置:数轴上的每 个整数点, ...

  5. 校门外的树 OpenJudge 1.6.06

    06:校门外的树 总时间限制:  1000ms 内存限制:  65536kB 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0 ...

  6. 【解题报告】VijosP1448校门外的树(困难版)

    原题: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的--如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:K=1,K=1,读入l.r ...

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

    校门外的树 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……, ...

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

    校门外的树 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,K= ...

  9. C语言 · 校门外的树

    算法提高 校门外的树   时间限制:1.0s   内存限制:256.0MB      问题描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的 ...

随机推荐

  1. SSD论文优秀句子

    1. Nonvolatile memory(e.g., Phase Change Memory) blurs the boundary between memory and storage and i ...

  2. 一个基本jquery的评论留言模块

    <div class="productDiscuss"> <div class="title"><span class=" ...

  3. AOP(以MVC中的过滤器为例)

    MVC里面的Filter public class AOPFilterAttribute : ActionFilterAttribute, IExceptionFilter { public void ...

  4. POJ2255二叉树

    题目大意就是给出你一个二叉树的前序和中序,要你求后序. 思路:二叉树的排序就是根据根节点的位置来定义的.所以找到二叉树的根节点是最重要的,二叉树的左子树和右子树也可以看成是二叉树,以此递归: #inc ...

  5. python参考手册 Read

    P28 复制 a = [1,2,3,[1,2]] b = a b is a # True c = list[a] # shallow copy c is a # False c[3][0] = 100 ...

  6. 常用面试sql语句

    1.编写一条sql语句,要修改一个字段的俩个值,比如把字段sex中的男改为女,女改为男. update m set m=(case when m='男' then '女' else '男' end) ...

  7. [转载]MongoDB的真正性能

    最近开始研究MySQL和MongoDB,发现这方面资料不多.尤其是真正的说到点子上的文章,太少了. 有一些对比测试的文章基本上都是瞎测,测试方法都测到了马腿上,得出的结论基本上都是NoSQL毫无价值 ...

  8. no identities are available for signing

    原地址:http://www.cnblogs.com/imzzk/p/3501868.html 今天将做好的app提交到app store,结果就出现标题上的错误.“No identities are ...

  9. 实现SELECT的全选,反选,AB选的JAVASCRIPT代码

    参考网上,用原生JS粗糙实现. 我发现用UIKIT的BUTTON会自动刷新我那核心的模态窗口,只好用另外的LABEL或CODE标签了. $(".btn-select-all").c ...

  10. 一个用于清除loadrunner产生log文件的批处理

    @echo off set work_path="%~dp0" for /R %%s in (*.txt,*.log) do ( del /f "%%s" ) ...