首页 > 其他分享 >计蒜客:公告板(线段树)

计蒜客:公告板(线段树)

时间:2024-10-30 20:42:14浏览次数:3  
标签:right int 线段 公告 rest 宽度 区间 计蒜客

 难点在于要把模型抽象出来。

第一眼看到题面,想到的是以公告板的高度作为线段树的区间,但看到h<=10^9以后,感觉又开不了这么大的数组。但实际上,最多只有n块公告,所以最极端的情况下不过只有n行,所以区间的真正大小是[1,min(n,h)]。

解决了区间的问题,再来考虑每个节点要维护的信息。我们希望从线段树中获得的是在区间[1,min(n,h)]中能放置新公告的最小下标,所以我们维护节点信息的可以是该区间已使用的最小宽度或者剩余的最大宽度,其中剩余的最大宽度更适合我们正向思考。

区间和节点信息的意义确认之后,我们就要为如何快速得到结果进行准备了。考虑到我们要获得的是最小下标,所以我们优先向左边的区间进行遍历,即当左子树代表的区间内有可以容纳该公告的行时就直接往左遍历。遍历优先级确认后,就可以写代码了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int h,w,n;
 4 vector<int> rest(200000 * 4, 0); //rest[p]表示p结点对应区间内的最大剩余宽度
 5 
 6 void modify(int p, int left, int right, int x, int y) {
 7     if (left == right) { //更新第x行的最大剩余宽度
 8         rest[p] += y;
 9         return;
10     }
11     int mid = (left + right) / 2;
12     if (x <= mid) {
13         modify(p * 2, left, mid, x, y);
14     } else {
15         modify(p * 2 + 1, mid + 1, right, x, y);
16     }
17     rest[p] = max(rest[p * 2], rest[p * 2 + 1]);
18 }
19 int query(int p, int left, int right , int x) {
20     if (rest[p] < x){
21         return -1;
22     }
23     if (left == right) {
24         return left;
25     }
26     int mid = (left + right) / 2;
27     if (x <= rest[p * 2]) { //优先往左遍历
28         return query(p * 2, left, mid, x);
29     }
30     if (x <= rest[p * 2 + 1]) {
31         return query(p * 2 + 1, mid + 1, right, x);
32     }
33 }
34 int main(){
35     cin >> h >> w >> n;
36     int len = min(h, n), temp;
37     for (int i = 1; i <= len; ++i) { //初始化剩余宽度
38         modify(1 , 1, len, i, w);
39     }
40     for (int i = 1; i <= n; ++i) {
41         scanf("%d", &temp);
42         int res = query(1, 1, len, temp);
43         if (res != -1)
44             modify(1, 1, len, res, -temp);
45         printf("%d\n", res);
46     }
47 }

 

标签:right,int,线段,公告,rest,宽度,区间,计蒜客
From: https://www.cnblogs.com/coderhrz/p/18516580

相关文章

  • 计蒜客:最甜的苹果(线段树)
     样例输入5612345Q15U36Q34Q45U29Q15样例输出5659 这题我们需要维护的信息,从区间的和变成了区间内的最大值。现在区间的内的某个值可能增大可能减小,若从上到下(从根到叶)进行节点更新,我们无法直接判断目前区间内的最大的节点。所以维护区间......
  • 题解:P3352 [ZJOI2016] 线段树
    首先,题目上说让期望乘上\((\frac{n(n+1)}{2})^q\)的目的就是让我们求方案数与值的乘积。然后我们考虑在操作过后一个位置上的值相对于原来的值肯定是不降的,于是可以想到对每一个值\(v\),原序列中所有\(\lev\)的元素一定构成了若干连续的区间。对每一个这样的区间而言,操作过......
  • js逆向实战之某市场监管公告服务平台返回数据解密
    声明:本篇文章仅用于知识交流分享,不用于其他用途练习网站:https://jzsc.mohurd.gov.cn/data/company解密过程分析访问网站,随便选择一个区域,点击查询,看触发哪些数据包。只有一个数据包,且其响应数据一看就是经过加密的。有经验的人就会条件反射是拦截器,全局搜索interceptors。......
  • P2839 [国家集训队] middle(二分+可持久化线段树)
    P2839[国家集训队]middle二分+可持久化线段树中位数经典做法,二分答案,将小于的部分看做\(-1\),大于等于的部分看做\(+1\),那么答案可以更大的条件就是区间和大于等于\(0\)(等于\(0\)可不可以取到看是下取整还是上取整,本题是上取整)。那么问题就是怎么判断有没有这样一个区间......
  • 新高一暑假第一期集训恢复性训练【数据结构-线段树晚测】(补)
    新高一暑假第一期集训恢复性训练【数据结构-线段树晚测】(补)A.[CF1045G]AIrobots我们先按视野降序排序,这样一个一个考虑,如果后面的能看到前面,那前面的也肯定能看到后面。这样,就是对于每一个机器人,在他前面有几个智商在\([q-k,q+k]\),位置在\([x-r,x+r]\)。那么把这个东......
  • 线段树初步理解
    今天ZRtes爆零咯,就不在tes里写了引言:以前一直只会用线段树2,线段树也是一直当做工具使用,一切线段树的科技除了线段树分治基本都不会,因此特作此文记之线段树的lazytag与pushdown为了保证时间复杂度,线段树在做区间修改的时候引入了lazytag的概念,目的是为了节省没必要的时......
  • 线段树?Lazytag?
    本文导读:本博客主要介绍了线段树的原理和构造的过程,以及一些例题,如果有不足的点,欢迎指出qwq.线段树\((1)_{36}\):什么是线段树?作为一个蒟蒻qwq,看到"线段树"三个字时,你想到了什么?蒟蒻:我知道!不就是"线段+树"吗!......作者:哎呀,你到底在说什么,还是我来解释吧...1.线段树......
  • 【故障公告】数据库服务器 CPU 100% 造成全站故障
    非常抱歉,今天下午16:03~16:33期间,我们使用的阿里云RDS实例(SQLServer2016标准版,16核32G)出现CPU100%问题,造成全站无法正常访问,由此给您带来很大的麻烦,请您谅解。发现故障后,我们通过阿里云RDS控制台进行了主备切换,由于CPU被占太满,主备切换失败,然后尝试重启实例,重启后......
  • 原创计算机毕业设计—69271 django重大公告卫生事件物资管理系统 (源码免费领)定制程序
    摘要随着信息技术的快速发展,计算机应用已经进入成千上万的家庭。随着物资数量的增加,物资库存管理也存在许多问题。物资数据的处理量正在迅速增加,原来的手工管理模式不适合这种形式。使用计算机可以完成数据收集、处理和分析,减少人力和物力的浪费。需要建立重大公告卫生事件......
  • zkw 线段树学习笔记
    一、简介zkw线段树专门用于线段树卡常,同时码量比普通线段树要小。原理是通过将线段树补成完全二叉树,直接找到第\(i\)个叶子节点(编号为\(p+i\)),然后从下往上更新,从而避免递归。这里常数p=1<<(__lg(n)+1),编号为\(p\)和\(p+n+1\)的叶子为虚点,编号为\(p+1\simp+n\)的......