【分块】bzoj1593 [Usaco2008 Feb]Hotel 旅馆

分块,记录每个块内包括左端点的最大连续白段的长度,

整个块内的最大连续白段的长度,

和包括右端点的最大连续白段的长度。

Because 是区间染色,所以要打标记。

至于怎样在O(sqrt(n))的时间内找到最左的白色段呢?非常恶心…… 要考虑跨块的白段和块内的白段,并且顺序不能反。(代码中高亮的部分)

这题完全体现不出分块编程复杂度低的优势,完全逊色于线段树。

So 综上,对于要进行复杂的成段修改的题目,分块的编程复杂度较高,几乎没有优势,不推荐写。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<algorithm>
  5 using namespace std;
  6 int len[300],lenl[300],lenr[300],n,m,l[300],r[300],num[50001],sum,sz,x,y;
  7 bool All[300],a[50001];
  8 int delta[300],op;
  9 int Res,Num;char C,CH[12];
 10 inline int G()
 11 {
 12     Res=0;C=‘*‘;
 13     while(C<‘0‘||C>‘9‘)C=getchar();
 14     while(C>=‘0‘&&C<=‘9‘){Res=Res*10+(C-‘0‘);C=getchar();}
 15     return Res;
 16 }
 17 inline void P(long long x)
 18 {
 19     Num=0;if(!x){putchar(‘0‘);puts("");return;}
 20     while(x>0)CH[++Num]=x%10,x/=10;
 21     while(Num)putchar(CH[Num--]+48);
 22     puts("");
 23 }
 24 void makeblock()
 25 {
 26     memset(delta,-1,sizeof(delta));
 27     sz=sqrt(n);
 28     for(sum=1;sum*sz<n;sum++)
 29       {
 30         l[sum]=(sum-1)*sz+1;
 31         r[sum]=sum*sz;
 32         for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
 33         len[sum]=lenl[sum]=lenr[sum]=sz;
 34       }
 35     l[sum]=sz*(sum-1)+1; r[sum]=n;
 36     for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
 37     len[sum]=lenl[sum]=lenr[sum]=r[sum]-l[sum]+1;
 38     for(int i=1;i<=sum;i++) All[i]=true;
 39 }
 40 inline bool Is_All(const int &p)
 41 {for(int i=l[p];i<=r[p];i++) if(a[i]) return false; return true;}
 42 inline void Pushdown(const int &p)
 43 {
 44     if(delta[p]!=-1)
 45       {for(int i=l[p];i<=r[p];i++) a[i]=delta[p];
 46       delta[p]=-1;}
 47 }
 48 inline void Work(const int &Lb,const int &Rb,const int &sym)
 49 {
 50     Pushdown(num[Lb]);
 51     for(int i=Lb;i<=Rb;i++) a[i]=sym;
 52     All[num[Lb]]=Is_All(num[Lb]);
 53     int cnt=0;
 54     for(int i=l[num[Lb]];i<=r[num[Lb]];i++) {if(a[i]) break; cnt++;}
 55     lenl[num[Lb]]=cnt; cnt=0;
 56     for(int i=r[num[Lb]];i>=l[num[Lb]];i--) {if(a[i]) break; cnt++;}
 57     lenr[num[Lb]]=cnt; cnt=0;
 58     int Longest=0;
 59     for(int i=l[num[Lb]];i<=r[num[Lb]];i++)
 60       {
 61           if(a[i]) cnt=0; else cnt++;
 62           if(cnt>Longest) Longest=cnt;
 63       }
 64     len[num[Lb]]=Longest;
 65 }
 66 inline void Update(const int &L,const int &R,const bool &sym)
 67 {
 68     if(num[L]==num[R]) Work(L,R,sym);
 69     else
 70       {
 71           Work(L,r[num[L]],sym);
 72           Work(l[num[R]],R,sym);
 73           for(int i=num[L]+1;i<num[R];i++)
 74             {
 75                 delta[i]=sym;
 76                 len[i]=lenl[i]=lenr[i]=sym ? 0 : r[i]-l[i]+1;
 77                 All[i]=sym ? false : true;
 78             }
 79       }
 80 }
 81 inline void YuDing()
 82 {
 83     int kua=0,kuasta;
 84     for(int i=1;i<=sum;i++)
 85       {
 86           if(kua) kua+=lenl[i];
 87         if(kua>=x)//预定sta~sta+x-1
 88           {
 89               Update(kuasta,kuasta+x-1,true);
 90               P(kuasta);
 91               return;
 92           }
 93           if(!All[i]) kua=0;
 94         if(!kua&&lenr[i])
 95             {
 96                 kua=lenr[i];
 97                 kuasta=r[i]-lenr[i]+1;
 98             }
 99           if(len[i]>=x)
100           {
101               Pushdown(i);
102               int cnt=0,Nowleft;
103             for(int j=l[i];j<=r[i];j++)
104               {
105                   if(a[j]) cnt=0; else cnt++;
106                   if(cnt==1) Nowleft=j;
107                   if(cnt==x)
108                     {
109                         Update(Nowleft,Nowleft+x-1,true);
110                         P(Nowleft);
111                         return;
112                     }
113               }
114           }
115       }
116     puts("0");
117 }
118 int main()
119 {
120     n=G();m=G();
121     makeblock();
122     for(int i=1;i<=m;i++)
123       {
124           op=G();x=G();
125           if(op==1) YuDing();
126           else {y=G(); Update(x,x+y-1,false);}
127       }
128     return 0;
129 }
时间: 2024-10-24 19:57:54

【分块】bzoj1593 [Usaco2008 Feb]Hotel 旅馆的相关文章

bzoj1593 [Usaco2008 Feb]Hotel 旅馆

1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 807  Solved: 447[Submit][Status][Discuss] Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排

1593: [Usaco2008 Feb]Hotel 旅馆

1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 489  Solved: 272[Submit][Status][Discuss] Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排

bzoj 1593: [Usaco2008 Feb]Hotel 旅馆

1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 800  Solved: 441[Submit][Status][Discuss] Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排

1593: [Usaco2008 Feb]Hotel 旅馆 (线段树)

1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 451  Solved: 262[Submit][Status][Discuss] Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排

【BZOJ】1593: [Usaco2008 Feb]Hotel 旅馆

[算法]线段树(经典线段树上二分) [题意]n个房间,m个询问,每次订最前的连续x个的空房间,或退订从x开始y个房间,求每次订的最左房间号. [题解]关键在于找连续x个空房间,经典二分. 线段树标记sum,lsum,rsum,表示最长连续房间,从左开始最长连续房间,从右开始最长连续房间. 对于区间k,如果k.sum<x,则无解. 否则,如果l(k).sum>=x,则在左区间. 否则,如果l(k).rsum+r(k).lsum>=x,则在中间,那么l(k).r-l(k).rsum+1就是答

【线段树区间合并】BZOJ1593-[Usaco2008 Feb]Hotel 旅馆

好无聊,以前写过没什么好讲的,水过.戳 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #define lson l,mid,rt<<1 5 #define rson mid+1,r,rt<<1|1 6 #define root 1 7 using namespace std; 8 const int MAXN=50000+50; 9 int n,m; 10 int ls

[Usaco2008 Feb][BZOJ1593] Hotel 旅馆|线段树

1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 417  Solved: 243[Submit][Status][Discuss] Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排

BZOJ 1592: [Usaco2008 Feb]Making the Grade 路面修整( dp )

最优的做法最后路面的高度一定是原来某一路面的高度. dp(x, t) = min{ dp(x - 1, k) } + | H[x] - h(t) | ( 1 <= k <= t ) 表示前 i 个路面单调不递减, 第 x 个路面修整为原来的第 t 高的高度. 时间复杂度O( n³ ). 令g(x, t) = min{ dp(x, k) } (1 <= k <= t), 则转移O(1), g() 只需在dp过程中O(1)递推即可, 总时间复杂度为O( n² ) 然后单调不递增也跑一遍

1611: [Usaco2008 Feb]Meteor Shower流星雨

1611: [Usaco2008 Feb]Meteor Shower流星雨 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1010  Solved: 446[Submit][Status][Discuss] Description 去年偶们湖南遭受N年不遇到冰冻灾害,现在芙蓉哥哥则听说另一个骇人听闻的消息: 一场流星雨即将袭击整个霸中,由于流星体积过大,它们无法在撞击到地面前燃烧殆尽, 届时将会对它撞到的一切东西造成毁灭性的打击.很自然地,芙蓉哥哥开