hiho一下21周 线段树的区间修改 离散化

离散化

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~

这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住。看到这个场景,小Hi便产生了这样的一个疑问——最后到底能有几张海报还能被看见呢?

于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作长度为L的一段区间,且有N张海报按照顺序依次贴在了宣传栏上,其中第i张海报贴住的范围可以用一段区间[a_i, b_i]表示,其中a_i, b_i均为属于[0, L]的整数,而一张海报能被看到当且仅当存在长度大于0的一部分没有被后来贴的海报所遮挡住。那么问题就来了:究竟有几张海报能被看到呢?

提示一:正确的认识信息量

提示二:小Hi大讲堂之线段树的节点意义

输入

每个测试点(输入文件)有且仅有一组测试数据。

每组测试数据的第1行为两个整数N和L,分别表示总共贴上的海报数量和宣传栏的宽度。

每组测试数据的第2-N+1行,按照贴上去的先后顺序,每行描述一张海报,其中第i+1行为两个整数a_i, b_i,表示第i张海报所贴的区间为[a_i, b_i]。

对于100%的数据,满足N<=10^5,L<=10^9,0<=a_i<b_i<=L。

输出

对于每组测试数据,输出一个整数Ans,表示总共有多少张海报能被看到。

样例输入
5 10
4 10
0 2
1 6
5 9
3 4
样例输出
5
线段树离散化(连续性)模板
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#define inf 2e9
#define met(a,b) memset(a,b,sizeof a)
typedef long long ll;
using namespace std;
const int N = 2e6+5;
const int M = 4e6+5;
int n,sum[N],m,re=0;
int Tree[N],lazy[N];
int num[N*2],ans[N];
map<int,int>mp;
struct man{
    int l,r;
}a[N*2];
void pushdown(int pos){
    if(Tree[pos]){
        Tree[pos<<1]=Tree[pos<<1|1]=Tree[pos];
        Tree[pos]=0;
    }return;
}

void update(int L,int R,int val,int l,int r,int pos) {
    if(l>=L&&r<=R) {
        Tree[pos]=val;
        return;
    }
    if(l+1==r)return;
    int mid=(l+r)>>1;
    pushdown(pos);
    if(L<=mid) update(L,R,val,l,mid,pos<<1);
    if(mid<R)update(L,R,val,mid,r,pos<<1|1);
}
void query(int L,int R,int l,int r,int pos) {
    if(Tree[pos]&&!ans[Tree[pos]]){
        ans[Tree[pos]]=1;
        re++;
        return;
    }
    if(l+1==r)return;
    int mid=(l+r)>>1;
    pushdown(pos);
    int ans=0;
    if(L<=mid) query(L,R,l,mid,pos<<1);
    if(R>mid) query(L,R,mid,r,pos<<1|1);
    return;
}
int main() {
    int ll,rr,cnt=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i].l,&a[i].r);
        num[cnt++]=a[i].l;
        num[cnt++]=a[i].r;
    }
    sort(num,num+cnt);
    int all=0;
    for(int i=0;i<cnt;i++)if(!mp[num[i]])mp[num[i]]=++all;
    for(int i=1;i<=n;i++)update(mp[a[i].l],mp[a[i].r],i,1,all,1);
    query(1,all,1,all,1);
    printf("%d
",re);
    return 0;
}
原文地址:https://www.cnblogs.com/jianrenfang/p/6139164.html