首页 > 其他分享 >POJ 3667 Hotel

POJ 3667 Hotel

时间:2022-10-25 14:05:25浏览次数:91  
标签:3667 return int Hotel tree else POJ 区间 include


题目链接:​​传送门​虽然是重题但还是要发一篇博客

维护最长01串
oh我之前写的好良心
再放上来

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <vector>
#include <iomanip>
#define
#define
#define

using namespace std;
struct node {
int l, r, w, lt, rt, t, f;
}tree[A];
int n, m, x, y, typ, ans;
void up(int k) {
tree[k].t = max(tree[k << 1].rt + tree[k << 1 | 1].lt, max(tree[k << 1].t, tree[k << 1 | 1].t));
//当前区间最长的一段可以是左儿子的右边开始最长区间长度加上左儿子的左边开始最长区间长度
//还可以是左儿子的区间最长长度或右儿子的区间最长长度
if (tree[k << 1].lt == tree[k << 1].w) tree[k].lt = tree[k << 1].lt + tree[k << 1 | 1].lt;
//可以是左儿子的区间长度加上右儿子的左边开始最长区间长度
else tree[k].lt = tree[k << 1].lt;
if (tree[k << 1 | 1].rt == tree[k << 1 | 1].w) tree[k].rt = tree[k << 1].rt + tree[k << 1 | 1].rt;
//可以是右儿子的区间长度加上左儿子的右边开始最长区间长度
//这两块可以并到一起
else tree[k].rt = tree[k << 1 | 1].rt;
}
void build(int k, int l, int r) {
tree[k].l = l; tree[k].r = r; tree[k].w = r - l + 1; //w维护这段区间的长度
if (l == r) {
tree[k].lt = tree[k].rt = tree[k].t = 1; //初值都为1
return;
}
int m = (l + r) >> 1;
build(k << 1, l, m);
build(k << 1 | 1, m + 1, r);
up(k);
}
void down(int k) { //标记下传
if (tree[k].f == 1) {
tree[k << 1].lt = tree[k << 1].rt = tree[k << 1].t = 0;
tree[k << 1].f = 1;
tree[k << 1 | 1].lt = tree[k << 1 | 1].rt = tree[k << 1 | 1].t = 0;
tree[k << 1 | 1].f = 1;
tree[k].f = 0;
//这是删除点,也就是退房
}
if (tree[k].f == 2) {
tree[k << 1].lt = tree[k << 1].rt = tree[k << 1].t = tree[k << 1].w;
tree[k << 1].f = 2;
tree[k << 1 | 1].lt = tree[k << 1 | 1].rt = tree[k << 1 | 1].t = tree[k << 1 | 1].w;
tree[k << 1 | 1].f = 2;
tree[k].f = 0;
//开房
}
}
void change(int k, int l, int r, int typ) {
if (l <= tree[k].l and r >= tree[k].r) {
if (typ == 1) {
tree[k].lt = tree[k].rt = tree[k].t = 0;
tree[k].f = 1;
//退房
}
else tree[k].lt = tree[k].rt = tree[k].t = tree[k].w, tree[k].f = 2;//开房
return;
}
down(k);
int m = (tree[k].l + tree[k].r) >> 1;
if (l <= m) change(k << 1, l, r, typ);
if (r > m) change(k << 1 | 1, l, r, typ);
up(k);
}
int ask(int k) {
//可能大多数人会觉得这里有判断是否在区间内的操作
//但这里的操作区间是1-n,所以就没有必要判断了
down(k);
//直接下放标记
if (tree[k << 1].t >= x) return ask(k << 1); //向左儿子找
else if (tree[k << 1].rt + tree[k << 1 | 1].lt >= x) return tree[k << 1].r - tree[k << 1].rt + 1;
//左右两端区间并起来能达到题目要求
//也就是明确了区间端点
//到这里就可以返回答案了
//就按题目要求返回左端点
else if (tree[k << 1 | 1].t >= x) return ask(k << 1 | 1); //向右儿子找
up(k);
}

int main(int argc, char const *argv[]) {
scanf("%d%d", &n, &m); build(1, 1, n);
while (m--) {
scanf("%d", &typ);
if (typ == 1) {
scanf("%d", &x);
if (tree[1].t < x) puts("0");
else {
ans = ask(1);
printf("%d\n", ans);
change(1, ans, ans + x - 1, 1); //要求查完之后把房开开
}
}
else {
scanf("%d%d", &x, &y);
change(1, x, x + y - 1, 2); //退房
}
}
return 0;
}


标签:3667,return,int,Hotel,tree,else,POJ,区间,include
From: https://blog.51cto.com/lyle/5794658

相关文章

  • POJ 2481 Cows
    题目链接:​​传送门​​问每条线段被包含了多少次把线段按左端点排序左端点相同的按右端点大的在前面这样就不用考虑左端点的影响了每次插入一条线段就将1-r加1询问r-i......
  • BZOJ 2295: 【POJ Challenge】我爱你啊
    题目链接:​​传送门​​看到题目就进来了#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<complex>#include<algorithm>#include<cl......
  • POJ 2390 (小数高精度乘法)
    小数高精度乘法m*(1+r/100)^yProgramP2390;constmaxn=40000;F=10;typearr=recordd:array[1..maxn]oflongint;len,doc:longint;end;var......
  • POJ 3278(BFS-搜索范围)
    这题是BFS水的主要是范围0<=n,k<=100000 但是有可能搜到200000……半天功夫才A.programP3278;constmaxn=200000;varn,k,i,j:longint;q,deep:array[1..maxn]of......
  • POJ 3692(匈牙利算法)
    匈牙利算法:b[]保存当前找交错路P的各点是否已被连通,a[]表示某点之前的点本题的2分图是取最大团(各点互相连通),利用2分图性质,可看成补图的最大独立集(各点互不连通)……Program......
  • POJ 2184(01背包+滚动数组)
    01背包模板题Programdd;constmaxn=1000;maxv=100000;minv=-100000;NULL=-2139062144;varn,i,j,ans,p,np:longint;ts,tf:array[1..maxn]oflongint;......
  • POJ 1950(不打表做法)
    这题就是搜……注意设定maxn要不然肯定爆maxn=1*10^最大位数/21234..89-11121314这样的Programaa;constmaxn=1000000000000000;varn,t:longint;a:array[1..15]......
  • POJ 3256(SPFA)
    这题只能对每一个点查一遍……有向图的话能用floyd,可是迫于时限用了SPFA。Programaa;constmaxk=10000;maxn=10000;maxm=10000;vark,n,m,i,j,l:longint;a:ar......
  • POJ 2110(最小生成树)
    这题的思路就是找一个范围,看看这个范围是否可行主流是二分Ans,我是先把点排序,求最小生成树检查首位的ProgramP2110;typeed=recordu,v,w:longint;end;vara......
  • POJ 1951(空串特判)
    这题的教训是要特判空串ProgramP1951;vars:string;len,i,j:longint;b:array[0..10000]ofboolean;functionisdight(x:longint):boolean;beginif(x>=65)an......