[swustoj 764] 校门外的树 Plus Plus

校门外的树 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<<2];
  
int tot;
int ans;
int x[N];
int lazy[N<<2];
bool flag[N<<2];
  
void pushdown(int rt)
{
    if(lazy[rt]!=-1)
    {
        lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
        lazy[rt]=-1;
    }
}
void build(int l,int r,int rt)
{
    lazy[rt]=-1;
    if(l==r) return;
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
}
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)>>1;
    if(R<=m) update(l,m,rt<<1,L,R,c);
    else if(L>m) update(m+1,r,rt<<1|1,L,R,c);
    else
    {
        update(l,m,rt<<1,L,m,c);
        update(m+1,r,rt<<1|1,m+1,R,c);
    }
}
void query(int l,int r,int rt)
{
    if(lazy[rt]!=-1)
    {
        if(!flag[lazy[rt]])
        {
            ans++;
            flag[lazy[rt]]=1;
        }
        return;
    }
    if(l>=r) return;
    pushdown(rt);
    int m=(l+r)>>1;
    query(l,m,rt<<1);
    query(m+1,r,rt<<1|1);
}
int main()
{
    int n,i;
    while(scanf("%d",&n)!=EOF)
    {
        ans=0;
        tot=0;
        memset(flag,0,sizeof(flag));
        for(i=0;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-1;i>0;i--)
        {
            if(x[i]-x[i-1]>1) x[tot++]=x[i-1]+1;
        }
        sort(x,x+tot);
        build(0,tot-1,1);
        for(i=0;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(0,tot-1,1,l,r,i);
        }
        query(0,tot-1,1);
        cout<<ans<<endl;
    }
    return 0;
}

原来搓代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 20005

struct tree
{
    int l,r;
}p[N<<2];
struct node
{
    int val,id,pos;
}h[N<<2];

int ans;
int color[N<<2];
bool flag[N<<2];
int change[N<<2];

bool cmp(node a,node b)
{
    return a.val<b.val;
}
void pushup(int rt)
{
    color[rt]=0;
}
void pushdown(int rt)
{
    if(change[rt]!=-1)
    {
        change[rt<<1]=change[rt<<1|1]=change[rt];
        color[rt<<1]=color[rt<<1|1]=change[rt];
        change[rt]=-1;
    }
}
void build(int l,int r,int rt)
{
    color[rt]=0;
    change[rt]=-1;//初始化
    if(l==r) return;
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
}
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)>>1;
    if(R<=m)
        update(l,m,rt<<1,L,R,c);
    else if(L>m)
        update(m+1,r,rt<<1|1,L,R,c);
    else
    {
        update(l,m,rt<<1,L,m,c);
        update(m+1,r,rt<<1|1,m+1,R,c);
    }
    pushup(rt);
}
void query(int l,int r,int rt)
{
    int m=(l+r)>>1;
    if(color[rt])
    {
        if(!flag[color[rt]])
        {
            ans++;
            flag[color[rt]]=1;
        }
        return;
    }
    if(l==r) return; //忘了加这一句、一直RE
    query(l,m,rt<<1);
    query(m+1,r,rt<<1|1);
}
int main()
{
    int n,i;
    while(scanf("%d",&n)!=EOF)
    {
        ans=0;
        memset(flag,0,sizeof(flag));
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].l,&p[i].r);
            h[i*2].val=p[i].l;
            h[i*2].id=i;
            h[i*2].pos=0;
            h[i*2+1].val=p[i].r;
            h[i*2+1].id=i;
            h[i*2+1].pos=1;
        }
        /* 离散化 */
        sort(h,h+n*2,cmp);
        int last=-1,total=0;
        for(i=0;i<n*2;i++)
        {
            if(h[i].val!=last) 
            {
                total++;
                if(i && h[i].val-h[i-1].val>1) 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(1,total,1);
        for(i=0;i<n;i++)
        {
            update(1,total,1,p[i].l,p[i].r,i+1);
        }
        query(1,total,1);
        cout<<ans<<endl;
    }
    return 0;
}
趁着还有梦想、将AC进行到底~~~by 452181625
原文地址:https://www.cnblogs.com/hate13/p/4047820.html