这个题本来我是想练堆用的,结果堆没练出来,倒是练了练线段树。

此题属于那种看起来特别简单,一做起来做出翔的那种;交了六遍,对拍了N年才A。

主要需要注意的是这么几点:

1、节点保存什么信息?

题目中让求的是距离最大,但这玩意儿在线段树中不太好办;

我一开始想当然地写成了r-l式的距离,结果合并信息的时候呵呵了。

更好的做法是保存区间中连续一段空橱子的个数:①设置变量意义时一定要从易于理解和调试的角度出发。

显然,最长连续区间的左右端点也是需要保存的,因为我们需要用它来求出球该放在什么地方。但是!若一个区间的长度为0,它的左右端点应该是哪里?

2、②若[l,r]的长度为0,则令l=r+1,r=l-1.

为什么?看看在合并的时候我们做了什么?

设struct TS{int lmax,lR,rmax,rL,max,L,R}

if(tree[node<<1].lR=((l+r)>>1)+1){

tree[node].lmax+=tree[node<<1|1].lmax;

tree[node].lR=tree[node<<1|1].lR;

}

这时,若tree[node<<1|1].lmax=0会发生什么呢?

若设此时tree[node<<1|1].lR=(l+r)>>1的话,则

tree[node<<1].lR=(l+r)>>1.

是正确的。

所以。。就这样吧。

3、③三个变量中选择最大的哪个该怎么做?

很容易混乱。。

条理清晰?

把条件都完整的列出来!

if(a>=b&&a>=c){}

if(b>=a&&b>=c){}

if(c>=a&&c>=b){}

4、球该放在哪?

显然球应该放在最长的连续无球橱子区间中,但是。。具体在哪里呢?

设区间[L,R]为一个最长连续无球橱子区间,且L>1,R<N.

则显然④球应该放在L-1与R+1的中位数的位置,才能使球与L-1和R+1的距离的最小值最大。

即x=(L-1+R+1)>>1=(L+R)>>1.

5、⑤特殊区间

从1往右延伸的区间与从N往左延伸的区间,球在这里的距离长度就是区间长度!

6、记录的max?

这时我们发现一个很大很大的问题!就是节点中记录max,它不是那个最短距离,最短距离应该是max+1>>1!

也就是说,若果我们按max的大小比较,永远在max最大的前提下选择左边的那个,很可能会导致只比当前选出的max小1而其+1>>1与当前选出的max相同且在其右边的max被漏掉导致全盘皆输!

但是,如果我们不按max来选,是否可能导致当前选出的max比较小,使得之后合成的max比实际选出的max要小呢?也就是说一个max差了1不算,但两个差了2就不一样了啊!

但是我们突然发现了一个问题!max不会被合成,唯一与max有关的运算只是Cmp;合成是交给lmax和rmax的,而lmax和rmax又不需要Cmp!

于是。。在无数遍的WA与摸爬滚打之中,我们终于找到了正解的道路。。

#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
struct TS{int lmax,rmax,max,L,R,lR,rL;
}tree[800000];
int point[1000001];
#define root 1,1,N
#define lson node<<1,l,(l+r)>>1
#define rson node<<1|1,((l+r)>>1)+1,r
inline void update(int node,int l,int r,int x,int A){if(l==r)if(A)tree[node]=(TS){1,1,1,x-1,x+1,x+1,x-1};else tree[node]=(TS){0,0,0,r,l,l,r};else{int m=(l+r)>>1;if(x>m)update(rson,x,A);else update(lson,x,A);tree[node].lmax=tree[node<<1].lmax;if(tree[node<<1].lR==m+1){tree[node].lmax+=tree[node<<1|1].lmax;tree[node].lR=tree[node<<1|1].lR;}else tree[node].lR=tree[node<<1].lR;tree[node].rmax=tree[node<<1|1].rmax;if(tree[node<<1|1].rL==m){tree[node].rmax+=tree[node<<1].rmax;tree[node].rL=tree[node<<1].rL;}else tree[node].rL=tree[node<<1|1].rL;int tmp=tree[node<<1].rmax+tree[node<<1|1].lmax;if(tree[node<<1].max+1>>1>=tree[node<<1|1].max+1>>1&&tree[node<<1].max+1>>1>=tmp+1>>1){tree[node].max=tree[node<<1].max;tree[node].L=tree[node<<1].L;tree[node].R=tree[node<<1].R;}elseif(tmp+1>>1>=tree[node<<1].max+1>>1&&tmp+1>>1>=tree[node<<1|1].max+1>>1){tree[node].max=tmp;tree[node].L=tree[node<<1].rL;tree[node].R=tree[node<<1|1].lR;}else{tree[node].max=tree[node<<1|1].max;tree[node].L=tree[node<<1|1].L;tree[node].R=tree[node<<1|1].R;}}//cout<<l<<","<<r<<":"<<tree[node].max<<"("<<tree[node].L<<"->"<<tree[node].R<<")"<<" "<<tree[node].lmax<<"("<<l<<"->"<<tree[node].lR<<")"<<" "<<tree[node].rmax<<"("<<tree[node].rL<<"<-"<<r<<")\n";
}
inline void build(int node,int l,int r){tree[node]=(TS){r-l+1,r-l+1,r-l+1,l-1,r+1,r+1,l-1};if(l!=r)build(lson),build(rson);
}
inline void out(int node,int l,int r){if(l!=r)out(lson),out(rson);else cout<<!tree[node].max;
}
int main(){freopen("CODEVS3032.in","r",stdin);//freopen("CODEVS3032.out","w",stdout);memset(tree,0,sizeof(tree));int N,M,flag,A,x,tot=0,l,m,r;scanf("%d%d",&N,&M);build(root);while(M--){scanf("%d%d",&flag,&A);if(flag-1)update(root,point[A],1);else{//cout<<tree[1].lmax<<" "<<(tree[1].max+1>>1)<<" "<<tree[1].rmax<<endl;if(tree[1].lmax>=tree[1].rmax&&tree[1].lmax>=tree[1].max+1>>1)x=1;elseif(tree[1].max+1>>1>=tree[1].rmax&&tree[1].max+1>>1>=tree[1].lmax)x=(tree[1].L+tree[1].R)>>1;else x=N;printf("%d\n",x);update(root,x,0);point[A]=x;}/*cout<<flag<<" "<<A<<":";out(root);cout<<endl;*/}
}

⑦重要总结:不论是多么简单的题,一定要写对拍!这个题中一半的问题全是拍出来的!有很多题都是看似简单实则不易。

[CODEVS3032]摆放球 解题报告相关推荐

  1. [zz][ZOJ Monthly]October 2008解题报告

    Connect4 Connect Four(Author: SONG, Yu[EZdestroyer]) 题目的背景就是Linux下的同名游戏,两个人在7*7的槽里轮流扔棋子,每次棋子都扔进某一列,棋 ...

  2. 解题报告:线性规划与网络流24题

    目录 A.飞行员配对方案问题 (二分图最大匹配)(最大流)[提高+/省选- ] B.太空飞行计划问题(最大权闭合图转最小割.最小割方案输出)[省选/NOI- ] C.最小路径覆盖问题(有向无环图最小路 ...

  3. LeetCode228场周赛解题报告

    LeetCode228场周赛解题报告 生成交替二进制字符串的最少操作数 原题链接 https://leetcode-cn.com/contest/weekly-contest-228/problems ...

  4. 解题报告 Toy Bricks

    Toy Bricks [题目描述] Ray又在NPC问题了:这里有一个箱子,还有若干个玩具. 我们可以假设玩具的数量是没有上限的.我们还知道这个箱子是不规则的,或者可以说,他的外形比较像一个矩形,但是 ...

  5. 2021-09-07 停课集训R8解题报告

    停课集训R8解题报告 小萌新到第5天才有空写题解,心都碎了 哼,哼,啊啊啊啊啊啊啊啊啊啊啊啊! R8:DP初级1 实话说,以前DP是我最讨厌的类型. 今天只A了2道题.可以说是十分痛苦 T1 问题 A ...

  6. 【解题报告】博弈专场 (CF 2000~2200)前五题

    [解题报告]博弈专场 (CF 2000+)前五题 A:Fox and Card Game | CF388C 题意 思路 代码 B:Berzerk | CF786A 题意 思路 代码 C:Ithea P ...

  7. 【解题报告】2015ACM/ICPC亚洲区上海站

    题目链接 A.An Easy Physics Problem(HDU 5572) 思路 我们可以将问题分为以下 22 种情况: 球与圆柱相撞 球与圆柱不相撞 我们可以通过判断以 AA 为起点以 V⃗  ...

  8. timus 1192. Ball in a Dream URAL 解题报告 平生第一个计算几何+高中物理

    timus   1192. Ball in a Dream    URAL  解题报告   平生第一个计算几何+高中物理 看来高中物理没白学,这个题用我仅剩下的高中物理学知识分析下竟然找到了方法,再加 ...

  9. 2022.2.18解题报告

    2022.2.18解题报告 T1.切蛋糕 题目描述: 思路: 首先,我们先来看一下最少用几刀就可以解决所有情况. 对于一个蛋糕,要分成至少三块,那么最少都要2刀,因为0刀或1刀分出的蛋糕数量都小于3. ...

最新文章

  1. 文件的记录c语言程序,计算机二级-C语言-程序填空题-190110记录-文件写入与文件读出显示...
  2. docker 安装nginx_Docker18安装Nginx和Apache实验
  3. linux shell 判断字符串是否为数字
  4. PsSetCreateProcessNotifyRoutineEx进程监控框架
  5. hashmap底层原理_Java集合 - HashMap原理(一) 概念和底层架构
  6. 2020ICPC沈阳 - United in Stormwind(推公式+FWT+SOSdp)
  7. ZooKeeper JMX
  8. Ba Gua Zhen
  9. linux mysql恢复数据_删库不跑路详解MySQL数据恢复
  10. Play framework 2.0 -应用程序全局设置(转)
  11. 「技术综述」人脸表情识别研究
  12. java字节码查看器_jclasslib 64位
  13. 如何将一个服务器加入域控中,Windows Server如何创建域并加入域
  14. Axure使用教程(三)、母版、Chart图表元件库
  15. pycharm文件名颜色含义
  16. ctfshow_萌新_萌新隐藏题
  17. 核磁谱图分析步骤_核磁一般氢谱和碳谱的解析步骤
  18. 将Unity虚拟相机视角画面显示在一个平面上
  19. Ansys2020R2的Fluent网格重排问题(reorder)
  20. 各种系统中密码文件的位置

热门文章

  1. 西南大学计算机学硕考研,西南大学计算机与信息科学学院14年学硕研招专业目录...
  2. scsi中DPO和FUA 是什么
  3. DSPE-PEG-MMPs; PEG-MMPs-DSPE ;聚乙二醇-基质金属蛋白酶-磷脂 ;磷脂-聚乙二醇-基质金属蛋白酶
  4. esp8266接入米家、小爱同学,附开源app控制
  5. pyhton爬取爱豆(李易峰)微博评论
  6. 苹果手机一卡通找不到了的解决方案 换手机 重下APP 找不到一卡通解决方案
  7. JVM堆大小与机器内存大小的一点探究
  8. 无线通信基础知识4:功率单位
  9. Selenium系列(二)对浏览器的常用操作
  10. unity 解决乱码_unity3d 中文乱码解决方法——cs代码文件格式批量转化UTF8