当前位置: 代码迷 >> 综合 >> 【线段树】[LUOGU USACO08FEB 酒店Hotel ] 区间连续最大
  详细解决方案

【线段树】[LUOGU USACO08FEB 酒店Hotel ] 区间连续最大

热度:67   发布时间:2024-01-17 00:04:37.0

题目:

题目链接:[LUOGU USACO08FEB 酒店Hotel ]
题解:
这个题,就是XOR的艺术和Glass Carving的结合,就是求长度为x的最小房间号的连续0,这样的话就是和Glass一样进行求线段树中的区间连续最大,再像XOR的艺术一样进行修改。

代码:

#include<bits/stdc++.h>
#define lk (k<<1)
#define rk (k<<1|1)
using namespace std;
inline int read()
{
    int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){
    if(ch=='-')w=-1;ch=getchar();}while(ch<='9'&&ch>='0')s=s*10+ch-'0',ch=getchar();return s*w;
}
const int sea=50100;
int n,m;
struct hit{
    int l,r,lm,rm,s,len,lazy;}tr[sea*4];
void build(int k,int l,int r)
{
    tr[k].l=l,tr[k].r=r;tr[k].lm=tr[k].rm=tr[k].s=tr[k].len=r-l+1;if(l==r) return; int mid=(l+r)/2;build(lk,l,mid); build(rk,mid+1,r);
}
void up(int k)
{
    if(tr[lk].s==tr[lk].len) tr[k].lm=tr[rk].lm+tr[lk].len;else tr[k].lm=tr[lk].lm;	if(tr[rk].s==tr[rk].len)tr[k].rm=tr[lk].rm+tr[rk].len;else tr[k].rm=tr[rk].rm;tr[k].s=max(max(tr[lk].s,tr[rk].s),tr[rk].lm+tr[lk].rm);
}
void down(int k)
{
    int l=tr[k].l,r=tr[k].r;if(l==r) return ;if(tr[k].lazy==1){
    tr[lk].lm=tr[lk].rm=tr[lk].s=tr[lk].len;tr[rk].lm=tr[rk].rm=tr[rk].s=tr[rk].len;tr[lk].lazy=tr[rk].lazy=1;}else if(tr[k].lazy==2){
    tr[lk].lm=tr[lk].rm=tr[lk].s=0;tr[rk].lm=tr[rk].rm=tr[rk].s=0;tr[lk].lazy=tr[rk].lazy=2;}tr[k].lazy=0;
}
void alter(int k,int x,int y,int ff)
{
    down(k);int l=tr[k].l,r=tr[k].r;if(l==x&&r==y){
    if(ff==1) tr[k].lm=tr[k].rm=tr[k].s=tr[k].len;else tr[k].lm=tr[k].rm=tr[k].s=0;tr[k].lazy=ff;	return ;}int mid=(l+r)/2;if(mid>=y) alter(lk,x,y,ff);else if(mid<x) alter(rk,x,y,ff);else alter(lk,x,mid,ff),alter(rk,mid+1,y,ff);up(k);
}
int ask(int k,int x)
{
    down(k);int l=tr[k].l,r=tr[k].r,mid=(l+r)/2;if(l==r) return l; if(tr[lk].s>=x) return ask(lk,x);if(tr[lk].rm+tr[rk].lm>=x) return mid-tr[lk].rm+1;return ask(rk,x);
}
int main()
{
    n=read(); m=read();build(1,1,n);for(int i=1;i<=m;i++){
    int f,x,y;f=read();if(f==1){
    x=read(); if(tr[1].s<x) puts("0");else{
    int p=ask(1,x); printf("%d\n",p);alter(1,p,p+x-1,2);}}else x=read(),y=read(),alter(1,x,y+x-1,1);}return 0;
}

Continue……