zoukankan      html  css  js  c++  java
  • [USACO13JAN] Seating

    https://www.luogu.org/problem/show?pid=3071

    题目描述

    To earn some extra money, the cows have opened a restaurant in their barn specializing in milkshakes. The restaurant has N seats (1 <= N <= 500,000) in a row. Initially, they are all empty.

    Throughout the day, there are M different events that happen in sequence at the restaurant (1 <= M <= 300,000). The two types of events that can happen are:

    1. A party of size p arrives (1 <= p <= N). Bessie wants to seat the party in a contiguous block of p empty seats. If this is possible, she does so in the lowest position possible in the list of seats. If it is impossible, the party is turned away.

    2. A range [a,b] is given (1 <= a <= b <= N), and everybody in that range of seats leaves.

    Please help Bessie count the total number of parties that are turned away over the course of the day.

    有一排n个座位,m次操作。A操作:将a名客人安置到最左的连续a个空位中,没有则不操作。L操作:[a,b]的客人离开。

    求A操作的失败次数。

    输入输出格式

    输入格式:

    • Line 1: Two space-separated integers, N and M.

    • Lines 2..M+1: Each line describes a single event. It is either a line of the form "A p" (meaning a party of size p arrives) or "L a b" (meaning that all cows in the range [a, b] leave).

    输出格式:

    • Line 1: The number of parties that are turned away.

    输入输出样例

    输入样例#1:
    10 4 
    A 6 
    L 2 4 
    A 5 
    A 2 
    
    输出样例#1:
    1 

    线段树
    实践再次证明:数组比结构体要快
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m,x,y,opl,opr;
    #define N 500001*4
    int maxx[N],max_l[N],max_r[N],sum[N],flag[N];
    void build(int k,int l,int r)
    {
        sum[k]=maxx[k]=max_l[k]=max_r[k]=r-l+1;
        if(l==r) return;
        int mid=l+r>>1;
        build(k<<1,l,mid);build((k<<1)+1,mid+1,r);
    }
    void down(int k)
    {
        flag[k<<1]=flag[(k<<1)+1]=flag[k];
        if(flag[k]==1)  
            maxx[k<<1]=max_l[k<<1]=max_r[k<<1]=maxx[(k<<1)+1]=max_l[(k<<1)+1]=max_r[(k<<1)+1]=0;
        else 
        {
            maxx[k<<1]=max_l[k<<1]=max_r[k<<1]=sum[k<<1];
            maxx[(k<<1)+1]=max_l[(k<<1)+1]=max_r[(k<<1)+1]=sum[(k<<1)+1];
        }  
        flag[k]=0;
    }
    int ask(int k,int l,int r)
    {
        if(l==r) return l;
        if(flag[k]) down(k);
        int mid=l+r>>1;
        if(maxx[k<<1]>=x) return ask(k<<1,l,mid);
        if(max_l[(k<<1)+1]+max_r[k<<1]>=x) return mid-max_r[k<<1]+1;
        return ask((k<<1)+1,mid+1,r);
    }
    void up(int k)
    {
        maxx[k]=max(max(maxx[k<<1],maxx[(k<<1)+1]),max_r[k<<1]+max_l[(k<<1)+1]);
        if(sum[k<<1]==maxx[k<<1])  max_l[k]=sum[k<<1]+max_l[(k<<1)+1];
        else max_l[k]=max_l[k<<1];
        if(sum[(k<<1)+1]==maxx[(k<<1)+1]) max_r[k]=sum[(k<<1)+1]+max_r[k<<1];
        else max_r[k]=max_r[(k<<1)+1];
    }
    void change(int k,int f,int l,int r)
    {
        if(l>=opl&&r<=opr)
        {
            if(f==1)
            {
                maxx[k]=max_l[k]=max_r[k]=0;
                flag[k]=1;
                return;
            }
            else
            {
                maxx[k]=max_l[k]=max_r[k]=sum[k];
                flag[k]=2;
                return;
            }
        }
        if(flag[k]) down(k);
        int mid=l+r>>1;
        if(opr<=mid) change(k<<1,f,l,mid);
        else if(opl>mid) change((k<<1)+1,f,mid+1,r);
        else 
        {
            change(k<<1,f,l,mid);
            change((k<<1)+1,f,mid+1,r);
        }
        up(k);
    }
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    int main()
    {
        int cnt=0;
        char p[2];
        read(n); read(m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",p);
            if(p[0]=='A')
            {
                read(x);
                if(maxx[1]<x) cnt++;
                else 
                {
                    opl=ask(1,1,n);
                    opr=opl+x-1;
                    change(1,1,1,n);
                }
            }
            else
            {
                read(opl); read(opr);
                change(1,2,1,n);
            }
        }
        printf("%d",cnt);
    }
  • 相关阅读:
    Git撤销某次分支的合并Merge
    Git撤销commit到未提交状态
    团队项目的Git分支管理规范
    命令行高效操作Git
    WebGoat安装说明
    您备案的网站未指向阿里云国内节点(不含香港)服务器,备案号可能被取消接入
    Java加密、解密--AES_Base64
    github 搜索技巧
    docker简介及安装常用开发软件
    springboot整合kafka实现消息推送
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7389937.html
Copyright © 2011-2022 走看看