• 题解 P3071 【[USACO13JAN]座位Seating】


     

    为什么没有题解?似乎讨论版里的也是错的=_= ......

    这样的话我就来写一篇吧lalal(`・ω・´)

    我有点怀疑标签,毕竟谁能想出这个怎么用(单调)队列写???

    懵逼

    其实我是用线段树写的。

    每个节点(区间)记录三个变量:

    sl[i]:从左往右有连续多少个空位

    sr[i]:从右往左有连续多少个空位

    s[i]:这个区间中最长连续多少个空位

     1 //ln指左孩子的区间包含多少座位
     2 //rn指右孩子的区间包含多少座位
     3 //rt指当前节点
     4 
     5 向上更新:
     6 
     7 inline void pu(int rt,int ln,int rn){
     8     s[rt]=max(max(s[ls],s[rs]),sr[ls]+sl[rs]);
     9     sl[rt]=sl[ls]+(sl[ls]==ln)*sl[rs];
    10     sr[rt]=sr[rs]+(sr[rs]==rn)*sr[ls];
    11 }
    12 
    13 向下更新:
    14 //add指懒惰标记
    15 inline void pd(int rt,int ln,int rn){
    16     if(!add[rt]||(!ln&&!rn))return;
    17     s[ls]=sl[ls]=sr[ls]=(add[rt]>0)*ln;
    18     s[rs]=sl[rs]=sr[rs]=(add[rt]>0)*rn;
    19     add[ls]=add[rs]=add[rt];add[rt]=0;
    20 }

    相信大家看代码应该是能看得懂的>_<

    那么我就来给完整代码了:

     1 #include<bits/stdc++.h>
     2 namespace ZDY{
     3 #define ll long long
     4 #define Fur(i,x,y) for(int i=x;i<=y;i++)
     5 #define in2(x,y) in(x);in(y)
     6 }using namespace ZDY;using namespace std;
     7 #define N 5000011
     8 #define ls rt<<1
     9 #define rs ls|1
    10 #define Z int m=(l+r)>>1
    11 #define lson l,m,ls
    12 #define rson m+1,r,rs
    13 ll s[N<<2],sl[N<<2],sr[N<<2];
    14 int n,q;
    15 short add[N];
    16 inline void pu(int rt,int ln,int rn){
    17     s[rt]=max(max(s[ls],s[rs]),sr[ls]+sl[rs]);
    18     sl[rt]=sl[ls]+(sl[ls]==ln)*sl[rs];
    19     sr[rt]=sr[rs]+(sr[rs]==rn)*sr[ls];
    20 }
    21 inline void pd(int rt,int ln,int rn){
    22     if(!add[rt]||(!ln&&!rn))return;
    23     s[ls]=sl[ls]=sr[ls]=(add[rt]>0)*ln;
    24     s[rs]=sl[rs]=sr[rs]=(add[rt]>0)*rn;
    25     add[ls]=add[rs]=add[rt];add[rt]=0;
    26 }
    27 inline void build(int l,int r,int rt){
    28     s[rt]=sl[rt]=sr[rt]=r-l+1;if(l==r)return;
    29     Z;build(lson);build(rson);
    30 }
    31 inline void upd(int L,int R,int l,int r,int rt,int v){
    32     if(L<=l&&r<=R){s[rt]=sl[rt]=sr[rt]=(v>0)*(r-l+1),add[rt]=v;return;}
    33     Z;pd(rt,m-l+1,r-m);
    34     if(L<=m)upd(L,R,lson,v);
    35     if(R>m)upd(L,R,rson,v);
    36     pu(rt,m-l+1,r-m);
    37 }
    38 inline int ask(int c,int l,int r,int rt){
    39     Z;pd(rt,m-l+1,r-m);
    40     if(s[ls]>=c)return ask(c,lson);
    41     else if(sr[ls]+sl[rs]>=c)return m-sr[ls]+1;
    42     else return ask(c,rson);
    43 }
    44 int main(){
    45      scanf("%d%d",&n,&q);build(1,n,1);
    46      int x,y,ans=0,pos;
    47      while(q--)
    48          if(sc()=='A'){
    49              scanf("%d",&x);
    50              if(s[1]<x)ans++;
    51              else{
    52                  pos=ask(x,1,n,1);
    53                  upd(pos,pos+x-1,1,n,1,-1);
    54              }
    55         }
    56          else{scanf("%d%d",&x,&y);upd(x,y,1,n,1,1);}
    57     cout<<ans<<endl;
    58 }
    View Code

     好像这题和P2894 [USACO08FEB]酒店Hotel 重复了...

  • 相关阅读:
    (转)基于C#的socket编程的TCP异步实现
    socket
    (转)抽象类、抽象属性、抽象方法
    (转)c# 互斥锁
    (转)C#连接OleDBConnection数据库的操作
    c# DLL封装并调用
    网络cmd命令
    (转)UCOSII在任务切换与出入中断时堆栈指针的使用
    app和bootloader跳转 MSP与PSP
    (转)stm32启动文件详解
  • 原文地址:https://www.cnblogs.com/mimiorz/p/9294546.html
Copyright © 2020-2023  润新知