线段树+区间离散化

校赛1007

题意 给你一个n(n<1e5),表示n个比赛直播,然后n个区间,l,r(0<=l,r<=1e9),表示比赛开始的时间和结束的时间,要同时把所有比赛看完,问最少要借多少台电脑(自己有一台电脑) 其实就是求区间重叠的最大值由于区间太大,所以离散化处理

思路:线段树区间更新 + 离散化

以区间的端点作为标记离散化,离散化后映射到线段树,将重复的端点去掉,然后重新排序,对每个区间二分确定映射后的区间,这里注意二分的时候左端点和右端点二分的判断条件是不同的

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define ull unsigned ll
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define len (Tr[rt].r-Tr[rt].l+1)
#define mem(a) memset(a,0,sizeof(a))
using namespace std;

struct Qu{
    ll l,r;
};
Qu Q[500000];
struct Node{
    int l,r;
    int maxn,lazy;
};
Node Tr[200000<<2];
int cnt;

void Push_up(int rt){
    Tr[rt].maxn=max(Tr[rt<<1].maxn,Tr[rt<<1|1].maxn);
}
void Push_down(int rt){
    Tr[rt<<1].lazy+=Tr[rt].lazy;
    Tr[rt<<1|1].lazy+=Tr[rt].lazy;
    Tr[rt<<1].maxn+=Tr[rt].lazy;
    Tr[rt<<1|1].maxn+=Tr[rt].lazy;
    Tr[rt].lazy=0;
}
void Build(int l,int r,int rt){
    Tr[rt].l=l,Tr[rt].r=r;
    if(l==r) return;
    int mid=l+r>>1;
    Build(lson);
    Build(rson);
}
void Add(int l,int r,int rt){
    if(Tr[rt].l==l && Tr[rt].r==r){
        Tr[rt].lazy++;
        Tr[rt].maxn++;
        return;
    }
    if(Tr[rt].lazy) Push_down(rt);
    int mid=Tr[rt].l+Tr[rt].r>>1;
    if(r<=mid) Add(l,r,rt<<1);
    else if(l>mid) Add(l,r,rt<<1|1);
    else Add(lson),Add(rson);
    Push_up(rt);
}
int fun(ll *a,ll s,int f){
    int l=1,r=cnt,ans=0;
    while(l<=r){
        int mid=l+r>>1;
        if(a[mid]<=s) ans=mid,l=mid+1;
        else r=mid-1;
    }
    if(!f) return ans+1; //左端点返回ans+1
    else return ans;     //右端点返回ans
}
ll a[250000];
int main(){
    int n,q,l,r;
    while(scanf("%d",&q)!=EOF){
        mem(Tr);
        ll K=1000000005;
        cnt=0;
        for(int i=0; i<q; i++){
            scanf("%lld%lld",&Q[i].l,&Q[i].r);
            a[cnt++]=Q[i].l,a[cnt++]=Q[i].r;
        }
        sort(a,a+cnt);
        int k=cnt;
        for(int i=1; i<k; i++) if(a[i-1]==a[i]) a[i-1]=K++,cnt--;
        sort(a,a+k);
        Build(1,cnt,1);
        for(int i=0; i<q; i++){
            l=fun(a,Q[i].l,0);
            r=fun(a,Q[i].r,1); //cout<<l<<" "<<r<<endl;
            Add(l,r,1);
        }
        printf("%d\n",Tr[1].maxn-1);
    }
    return 0;
}
时间: 2024-10-13 05:59:46

线段树+区间离散化的相关文章

hiho1079 : 离散化(线段树+区间离散化)

#1079 : 离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住.看到这个场景,小Hi便产生了这样的一个疑问--最后到底能有几张海报还能被看见呢? 于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

POJ 2528 Mayor&#39;s posters(线段树区间染色+离散化或倒序更新)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59239   Accepted: 17157 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

poj-----(2528)Mayor&#39;s posters(线段树区间更新及区间统计+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 43507   Accepted: 12693 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ 2528 Mayor&#39;s posters (离散化+线段树区间更新)

Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for

poj 2528 Mayor&#39;s posters(线段树区间覆盖、离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 49385   Accepted: 14304 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

线段树区间更新,区间统计+离散化 POJ 2528 Mayor&#39;s posters

题意:有一个很长的板子(10000000长),在上面贴n(n<=10000)张海报,问最后从外面能看到几张不同的海报. 因为板子有10000000长,直接建树肯定会爆,所以需要离散化处理,对于每张海报,有两个端点值,最后能看到几张海报跟他们的端点值的相对大小有关,跟绝对大小无关,所以就把所有海报的端点离散化处理,总共2n个端点,排序去重,对应p(p<=2n)个点.然后建树,因为p不超过20000,所以这样就可以接受了.区间更新时,因为我们只关心最外面海报的颜色有多少种,所以向下传递节点信息的时

POJ - 2528 Mayor&#39;s posters (离散化+线段树区间修改)

https://cn.vjudge.net/problem/POJ-2528 题意 给定一些海报,可能相互重叠,告诉你每个海报的宽度(高度都一样的)和先后叠放顺序,问没有被完全盖住的有多少张? 分析 海报最多10000张,但是墙有10000000块瓷砖长,海报不会落在瓷砖中间. 如果直接建树,就算不TLE,也会MLE.即单位区间长度太多. 其实10000张海报,有20000个点,最多有19999个区间.对各个区间编号,就是离散化.然后建树. 可以直接进行区间修改,最后再统计. 这里采用比较巧妙的

POJ - 2528Mayor&#39;s posters (离散化+线段树区间覆盖)

The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the