• 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
    ");
            else printf("NO
    ");
        }
        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
    ");
            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
    ");
                else printf("NO
    ");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    图解Go里面的互斥锁mutex了解编程语言核心实现源码
    day04 NTFS安全权限 | 文件共享服务器
    day03 用户与组管理 | 远程管理
    关于VMware的一些资源|IOS|序列号
    day03 批处理
    day02-IP地址详解
    test1
    simulink产生周期矩形波和8421码
    矩阵连乘问题的算法复杂度的计算--卡塔兰数(Catalan数)的数学推导和近似公式
    找出"吸血鬼数"(Java)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8452573.html
Copyright © 2020-2023  润新知