HihoCoder 1590 : 紧张的会议室(区间最大+离散化)

时间限制:20000ms

单点时限:2000ms

内存限制:256MB

描述

小Hi的公司最近员工增长迅速,同时大大小小的会议也越来越多;导致公司内的M间会议室非常紧张。

现在小Hi知道公司目前有N个会议,其中第i个会议的时间区间是(Si, Ei)。 注意这里时间区间可以视为是开区间,也就是说(3, 5)和(5, 6)不会被视为是同时进行的会议。

小Hi想知道如果他新增一个会议,时间区间是(X, Y),会不会导致出现会议室不够用的情况?

已知目前的N个会议不会导致会议室不够用。

输入

第一行包含两个整数:N和M。

以下N行每行两个整数Si和Ei,代表一个会议的时间区间。

之后一行包含一个整数Q,代表小Hi询问的次数。

以下Q行每行包含两个整数Xi和Yi,表示小Hi希望新增的会议时间。

对于30%的数据,1 <= N, M, Q <= 1000

对于100%的数据,1 <= N, M, Q <= 100000 0 <= Si < Ei <= 100000000 0 <= Xi < Yi <= 100000000

输出

对于每一次询问,输出YES或者NO。YES代表会议室够用,NO代表会议室不够用。

样例输入
3 1
1 2
3 4
5 6
2
2 3
2 4
样例输出
YES
NO

思路: 前缀和性质,[x,y]覆盖,则sum[x]++,sum[y+1]--,正好题目给定的是左开右闭[x,y),则直接离散化,求区间最大。

开始用树状数组,一直超时。后来改成倍增就ok了。

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1000010;
int x[maxn],y[maxn],s[maxn],e[maxn],sum[maxn],q[maxn];
int tmp,tmp2,cnt,R[maxn],dp[maxn][20];
int max(int a,int b){ if(a>b) return a; return b;}
int read()
{
    int res=0; char c=getchar();
    while(c>‘9‘||c<‘0‘) c=getchar();
    while(c>=‘0‘&&c<=‘9‘){res=res*10+c-‘0‘; c=getchar(); }
    return res;
}
int RMQ()
{
    for(int i=1;i<=cnt;i++) dp[i][0]=sum[i];
    for(int i=1;i<20;i++)
     for(int j=1;j+(1<<i)<cnt;j++)
      dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
int query(int l,int r)
{
    int k=log2(r-l+1);
    return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
    int N,M,Q,i,j,Max=0;
    scanf("%d%d",&N,&M);
    for(i=1;i<=N;i++){
        scanf("%d%d",&s[i],&e[i]);
        s[i]++; e[i]++;
        q[++cnt]=s[i];
        q[++cnt]=e[i];
    }
    scanf("%d",&Q);
    for(i=1;i<=Q;i++){
        scanf("%d%d",&x[i],&y[i]);
        x[i]++;  y[i]++;
        q[++cnt]=x[i];
        q[++cnt]=y[i];
    }
    sort(q+1,q+cnt+1);
    unique(q+1,q+cnt+1);
    for(i=1;i<=N;i++){
        tmp=lower_bound(q+1,q+cnt+1,s[i])-q; sum[tmp]++;
        tmp=lower_bound(q+1,q+cnt+1,e[i])-q; sum[tmp]--;
    }
    for(i=1;i<=cnt;i++) {
         sum[i]+=sum[i-1];
         Max=max(Max,sum[i]);
    }
    RMQ();
    for(i=1;i<=Q;i++){
        tmp=lower_bound(q+1,q+cnt+1,x[i])-q;
        tmp2=lower_bound(q+1,q+cnt+1,y[i])-q;
        if(query(tmp,tmp2-1)<M) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

超时代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=5000010;
int x[maxn],y[maxn],s[maxn],e[maxn],sum[maxn],q[maxn];
int tmp,tmp2,cnt,R[maxn];
int max(int a,int b){ if(a>b) return a; return b;}
int read()
{
    int res=0; char c=getchar();
    while(c>‘9‘||c<‘0‘) c=getchar();
    while(c>=‘0‘&&c<=‘9‘){res=res*10+c-‘0‘; c=getchar(); }
    return res;
}
void add(int i,int val)
{
    while(i<=cnt){
        R[i]=max(R[i],val);
        i+=(-i)&i;
    }
}
int query(int l,int r)
{
    int res=0;
    while(l<=r&&r){
        while(r-(-r)&r>=l&&r) {
            res=max(res,R[r]);
            r-=(-r)&r;
        }
        if(r>=l) res=max(res,sum[r--]);
    } return res;
}
int main()
{
    int N,M,Q,i,j,Max=0;
    scanf("%d%d",&N,&M);
    for(i=1;i<=N;i++){
        scanf("%d%d",&s[i],&e[i]);
        s[i]++; e[i]++;
        q[++cnt]=s[i];
        q[++cnt]=e[i];
    }
    scanf("%d",&Q);
    for(i=1;i<=Q;i++){
        scanf("%d%d",&x[i],&y[i]);
        x[i]++;  y[i]++;
        q[++cnt]=x[i];
        q[++cnt]=y[i];
    }
    sort(q+1,q+cnt+1);
    unique(q+1,q+cnt+1);
    for(i=1;i<=N;i++){
        tmp=lower_bound(q+1,q+cnt+1,s[i])-q; sum[tmp]++;
        tmp=lower_bound(q+1,q+cnt+1,e[i])-q; sum[tmp]--;
    }
    for(i=1;i<=cnt;i++) {
         sum[i]+=sum[i-1];
         add(i,sum[i]);
         Max=max(Max,sum[i]);
    }
    for(i=1;i<=Q;i++){
        if(Max>M) printf("NO\n");
        else {
            tmp=lower_bound(q+1,q+cnt+1,x[i])-q;
            tmp2=lower_bound(q+1,q+cnt+1,y[i])-q;
            if(query(tmp,tmp2-1)<M) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/8452573.html

时间: 2024-10-12 09:41:23

HihoCoder 1590 : 紧张的会议室(区间最大+离散化)的相关文章

hiho 1590 - 紧张的会议室。区间问题

题目链接 小Hi的公司最近员工增长迅速,同时大大小小的会议也越来越多:导致公司内的M间会议室非常紧张. 现在小Hi知道公司目前有N个会议,其中第i个会议的时间区间是(Si, Ei). 注意这里时间区间可以视为是开区间,也就是说(3, 5)和(5, 6)不会被视为是同时进行的会议. 小Hi想知道如果他新增一个会议,时间区间是(X, Y),会不会导致出现会议室不够用的情况? 已知目前的N个会议不会导致会议室不够用. 输入 第一行包含两个整数:N和M. 以下N行每行两个整数Si和Ei,代表一个会议的时

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

URAL 1019. Line Painting 线段树 区间合并 离散化

题目来源:URAL 1019. Line Painting 题意:求最长的一段全部为白色的区间 思路:线段树成段更新 区间合并 离散化 这里对应的是一段区间 所以每次不是m+1 而是 l m 和 m r 了 另外我加上了0 和 10^9 这两个点 每一段区间(l, r)我记录的是l和r之间有多少条线段 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const

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

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

Mayor&#39;s posters-POJ2528 区间染色+离散化

题意: 在一面长度为10000000 的墙上贴广告,告诉你每张海报的l,r(1 <= li <= ri <= 10000000.),让你求最后有几张海报露出来 链接:http://poj.org/problem?id=2528 思路: 由于数据较大,直接开数组不现实,所以我们考虑将每个点离散化,由于这里可能存在原本不相邻的点在离散化后变成相邻 例如三张海报分别为1-5,1-2,4-5,将数据离散化后1,2,4,5分别对应1,2,3,4,此时我们发现用离散化之后的数据得出来的结果 是2,但

Codeforces 138C(区间更新+离散化)

题意:有n棵树在水平线上,给出每棵树的坐标和高度,然后向左倒的概率和向右倒的概率,和为1,然后给出了m个蘑菇的位置,每一个蘑菇都有一个魔法值,假设蘑菇被压死了,也就是在某棵树[a[i] - h[i], a[i]) 或 (a[i], a[i] + h[i]]范围内.魔法值就没有了.仅仅有生存下来的蘑菇才有魔法值,问生存下来的蘑菇的魔法值的期望. 题解:能够看到n和m的范围是1e5.而坐标范围是1e9.所以肯定要离散化,然后更新每一个区间的概率值,单点查询每一个蘑菇所在区间的概率值乘其魔法值. #i

poj 2528(区间修改+离散化)

题意:有一个黑板上贴海报,给出每个海报在黑板上的覆盖区间为l r,问最后多少个海报是可见的. 题解:因为l r取值到1e7,肯定是要离散化的,但普通的离散化会出问题,比如[1,10],[1,4],[4,6]普通得到答案是2,但其实是3,改进的离散化方法如果两个数字相差大于1,就在中间补一个数字. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> usin