XTUOJ 区间覆盖总长(线段树+离散化)



区间覆盖总长

[ Submit Code ] [ Top 20 Runs ]
Acceteped : 43   Submit : 235
Time Limit : 3500 MS   Memory Limit : 65536 KB
 

Description

题目描述

在X轴上给你一些线段,问被这些线段覆盖的区间长。

输入

每个样例的第一行是一个整数K(K≤10000),表示线段的个数,如果K=0表示输入结束。以后的K行,每行为一个线段的左右端点x1,x2,(0 ≤ x1 < x2 ≤ 1,000,000,000)。

输出

每行输出一个样例的结果。

样例输入

2
1 2
2 3
3
1 3
0 2
5 6
0

样例输出

2
4
 

区间覆盖总长

[ Submit Code ] [ Top 20 Runs ]
Acceteped : 43   Submit : 235
Time Limit : 3500 MS   Memory Limit : 65536 KB
 

Description

题目描述

在X轴上给你一些线段,问被这些线段覆盖的区间长。

输入

每个样例的第一行是一个整数K(K≤10000),表示线段的个数,如果K=0表示输入结束。以后的K行,每行为一个线段的左右端点x1,x2,(0 ≤ x1 < x2 ≤ 1,000,000,000)。

输出

每行输出一个样例的结果。

样例输入

2
1 2
2 3
3
1 3
0 2
5 6
0

样例输出

2
4
 这是在XTUOJ上的一道题 http://202.197.224.59/exam/index.php/problem/read/id/1126

因为开不了10^9这么的的数组,先离散化处理下(这是很常见的操作,一定要掌握)
连pushup和pushdown都不需要,所以非常适合线段树入门


#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N = 20010;

struct acm
{
    int lt;
    int rt;
    int lazy;
}node[N*4];
int r[N],x[N],y[N];
int ans;
void build(int l,int r,int s)
{
    node[s].lt=l;
    node[s].rt=r;
    node[s].lazy=0;
    if(node[s].rt-node[s].lt==1)
        return;
    int mid=(l+r)>>1;
    build(l,mid,s<<1);
    build(mid,r,s<<1|1);
}
void update(int l,int r,int s)
{
    if(node[s].lt==l&&node[s].rt==r)
    {
        node[s].lazy=1;
        return;
    }
    if(node[s].lt+1==node[s].rt)
        return;
    int mid=(node[s].lt+node[s].rt)>>1;
    if(r<=mid)
        update(l,r,s<<1);
    else if(l>=mid)
        update(l,r,s<<1|1);
    else
    {
        update(l,mid,s<<1);
        update(mid,r,s<<1|1);
    }

}
void query(int s)
{
    if(node[s].lazy==1)
    {
        ans+=r[node[s].rt-1]-r[node[s].lt-1];
        return;
    }
    if(node[s].lt+1==node[s].rt)
        return;
    query(s<<1);
    query(s<<1|1);
}
int main()
{
    int k;
    while(scanf("%d",&k)&&k)
    {

        int cnt=0;
        ans=0;
        memset(r,0,sizeof(r));
        build(0,N,1);
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            r[cnt++]=x[i];
            r[cnt++]=y[i];
        }
        sort(r,r+cnt);
        cnt=unique(r,r+cnt)-r;
        for(int i=1;i<=k;i++)
        {
            int ll=lower_bound(r,r+cnt,x[i])-r+1;
            int rr=lower_bound(r,r+cnt,y[i])-r+1;
            update(ll,rr,1);

        }
        query(1);
        printf("%d\n",ans);

    }
}

你可能感兴趣的:(树状数组&&线段树)