2019-9-10做题记录

题目分三种,一种是$gyfan$上课讲的,一种是$yyb$一年之前做的,一种是$aysn$现在做的。而我的水平介于第二种和第三种之间。

1、【BZOJ1926】粟粟的书架(前缀和、主席树):

对于多行多列的情况,我们要维护一个多维的前缀和。

$value_{i,j,k}$ 从$(1,1)$到$(i,j)$的矩阵中数值$>=k$的数的总和

$num_{i,j,k}$ 从$(1,1)$到$(i,j)$的矩阵中数值$>=k$的数的个数

然后直接二分最小的一个书的页数就可以了。

对于一行的情况,我们为什么不这么搞了呢?因为这样搞数组开不下($n\le 500,000$),所以我们用主席树,在值域上二分(主席树长度$\le 1000$,好鸡肋啊)。

但是仔细想想,其实也不需要这样,我们可以把第一维压一压,比如序列上每$10$个共用一个$i$,这样不仅数组能开下,查询的时候多一个$10$的常数就可以了。

本质上,这道题可以用前缀和的原因就是主席树的值域比较小。

2、【BZOJ3626】LCA(树链剖分,Link-Cut Tree)

$aysn$在研学游的时候给我讲的神仙题,但是那时候窝太弱了,啥都没听懂,这次$yyb$说的可一定要学会啊。

花了10分钟颓了一个式子,发现就是求主席树上一条链上的$[l,r]$数的个数,可以从下到上算一遍前缀和、再从上到下算一遍前缀和,但是因为是线段树合并的加,所以复杂度会假,优化的方法也很简单,直接在下到上算的时候把全局打个$+1$的懒标记,再给自己打个$-1$的懒标记,这样就算出来了下至上的深度,要求上至下的直接再开一棵全局线段树减一下。(可能口胡的是假的,也可能会有更好的方法,谁知道呢?)

晚上看了$yyb$,发现和$aysn$的方法是一样的,就是考虑一个动态的过程,对于区间$[l,r]$我们把其中所有的元素找到,把他们到根的所有点$+1$,然后查询$z$到根上的和是多少,(不难想到,在这里和我颓的是一个东西,但是我把它复杂化了,其实不用记录具体是谁的信息,只需要记录数量,正如$zhhx$说的中国象棋,把状态压缩$dp$改为记录$0$有多少个,$1$有多少个,$2$有多少个,二有多少个被压了。。。),然后发现,这个贡献是可以减的,即把$[l,r]$分成$[1,r]$和$[1,l-1]$,我们只要每次树链剖分把当前的$i$到根的所有点$+1$,然后查找需要的$z$的值就可以了。

很显然,$aysn\ and\ yyb$的做法更好,我需要加油了。

3、【BZOJ4012】开店

开始应付不过来了。

在线、不带修改、求树上权为$[l,r]$的所有点到$x$的距离之和。

离线很好做,把权值离散化之后离线,把$[l,r]$分成$[1,r]$和$[1,l-1]$,考虑一个数据结构支持插入点和查询某点到所有点的距离之和。

这类问题显然要无根树转有根树,我们维护所有点到根的距离之和,如果把根转为$x$点,对于$x$的根上所有点,记为$i$(不严谨一下,$i+1$为$i$的父亲),有$$ans+=(-2dis[i]+dis[x])(siz[i]-siz[i-1])$$,然后拆相,把只和$x$有关系的提出来,直接算;把和$i$有关的放在$i$的位置上。就可以了(这样说好抽象啊,但我也没有其他别的办法了),然后就是像上一题那样树链剖分,链上修改和查询

真是日了狗了,上面写的全是假的,真的其实很简单,不要一起考虑,一个一个分别考虑。$$ans=\sum_{i=1}^{n}{dis_i+ndis[x]-2dis[LCA(x,i)]}$$,然后就用到了上面推的方法,直接记录每条链被覆盖的次数就好了(这就是$LCA$的暴力求法,把一个点上面的点涂色,然后另一个点向上最先碰到的有颜色的点就是它们的$lca$),然后对于在线的情况,对树链剖分的线段树可持久化。这样时间和空间都是两个$log$的。(发现没用到度数小于等于$3$的条件)

看到题解还有点分树的做法(度数的限制),可以下课时$yy$一下。

$aysn$说有三种方法

  • 动态点分树$+vector$,处理点到分治中心距离的前缀和。
  • 上述做法
  • 二进制分组$+$虚树($UR\#14$思考熊)

4、【BZOJ2006】【NOI2010】超级钢琴

傻逼垃圾裸题。

使用的方法和【十二省联考】异或粽子一模一样,让我退役的傻逼题,如果当场做出来了,我那一天可以进全省$7$,$8$名的,$day2$就一定不会崩盘了。结果我在考场上写了$4$个小时还是没有写出来,这,就是命吗?曾经,我在九年级上的一次期末考试中考到很好,我却因此得意忘形,最后在中考时考砸了,上了八中。我也曾想,把那一次的成功加到中考那一次,但是已经没有机会了,我想,我更应该要庆幸,这样的失误不是在最后一次。

只是把可持久化$trie$树换成主席树。

神奇的是,考场上的我直接想出来了那一题,而这一题是我在$aysn$提示之下(他说这道题和异或粽子相似)才想出来的。可能是码力提高了,但是思维却下降了吧。顾此失彼。

5、【BZOJ1146】网络管理

树上带修主席树。

Count On A Tree套一个$bit$。

怎么套?反正我是觉得很神奇,要我想我肯定想不出来。

我是这么想的:每一棵线段树是维护自己到根的信息,如果查询时还能顺着父亲跳$lowbit(x)$位,那么修改呢?岂不是要把下面的每条链的那个位置都修改,那样复杂度不就假了吗。

而题解就很神奇,充分利用了贡献的可加减性,先树链剖分,求出第一类$dfs$序,我们就在第一类$dfs$序上建后缀数组,还是一样的套路$i$的集合里包括$i,i-lowbit(i),(i-lowbit(i))-lowbit(i-lowbit(i))...$的信息,要修改的时候对$start[x]$修改,对$end[x]+1$反修改,这样使得修改的东西的影响之存在于一棵子树中,然后查询只查$start$,我至今没有看懂为什么这样是对的,可能马上睡一觉就知道了。

upd2019.9.11:还没睡呢,刚刚在洗澡就明白了,这是第二类$dfs$序,即括号序列,只不过把一些本应该在一起的右括号缩到了一起,是不影响结果的。

6、【BZOJ4556】字符串(后缀数组,主席树)

在北京神仙大酒店的厕所里面,$aysn$神仙在做题,而我在厕所$yy$一道自己出的题,好像跟子串的子串有关系,好像是用后缀自动机做的,我也忘了那天晚上想的是什么题,只能回想起来北京的小姐姐好好看啊。但是$CTS$和$APIO$却成为了我们最后一次相见。。。。

题是好题,但是我的脑子真的是转不动了,可能什么都想不出来了。

很显然二分长度,把不合法的第一个串的开头去掉(看成值域),得到一个区间,对于$height$数组的一路取$min$(看成序列),肯定也有一个区间,我们就是要检查这两个区间有没有交。

$RMQ$+二分求得“一路取$min$的区间”,然后对应到两棵线段树上,看看确定的区间有没有差值不为$0$的。

7、【SYCOJ279】滑稽♂树

水题,不写了。

8、【HDU5919】Sequencell

首先看到这道题转换前驱。

然后相当于在第$r$棵树和第$l-1$棵树的差里找$<l$的个数,然后我们二分一个中间位置出来,带入检验看看是不是中位数。

但是现在要优化(两个$log$),发现这样做可能没有充分利用主席树的功能(主席树可以查区间,但是这样查的左区间全是$0$,浪费了),因为一个元素有且仅有一个前缀、一个前缀也有且仅有一个后缀,所以这大概是一个对于排列的关系,我们可以把它翻过来,这样直接对应到$l$一棵树上,然后查$l..r$,在值域上二分,就可以做到一个$log$了。

9、【CF813E】Army Creation

思维好题。

首先,前驱转换。

前驱=$k$次前驱即可。

10、【CF484E】Sign on Fence

$yyb$说和$aysn$神仙题排序是一个套路,我只能$orz$了。

最小的最大,二分答案,把小于答案的都视为$0$,把大于答案的都视为$1$,然后就是让$[l..r]$中最长的一串$1$大于等于$k$。

主席树,按权值大小插进去,线段树要多维护一些信息(中间、左、右),每次二分一个答案,检查$[l..r]$是否大于等于$k$的。这样是两个$log$的。

由于洛谷题解第一篇说这题可以做到一个$log$,所以大部分人做的都是两个$log$的,所以我的是可以被接收的。

11、【BZOJ2653】Middle

和上一题是一个套路,二分答案,把小于等于答案的都视为$0$,把大于答案的都视为$1$,如果存在一段区间$0$的个数比$1$多$1$或者一样多,也就是$1$的个数是总个数除以$2$,那么这个二分的答案就是可行的。

应该把小于等于的视为$-1$,大于的视为$+1$,然后求$[a,b]$的最大右子段和和$[c,d]$最大左子段和。再次重申,二分答案之后,只需判断的东西是一个区间,并不是某个点,常常点的问题(最值)二分之后变成求一个可行解,而区间的问题变成求一个最大值。

然后用主席树维护就可以了。

12、【JSOI2018】列队

首先,很显然的,集合之后,每个人相对位置不变。

主要是想找到一个排名$k$,让$a[k]$向右走到$l+k-1$,并且$a[k+1]$向左走到$l+k$,也就是说,$a[k]$是分界线。

即$a[k]\le l+k-1$且$k$最大。

然后我们把$r$和$l-1$的线段树挑出来,在权值上二分,$t2[x].cnt-t1[x].cnt$就是$k$,然后当前值域的范围就是二分出来的$a[k]$的范围。

13、【TJOI2018】异或

宝宝惊呆了。

本来以为是神仙线性基,后来发现只用和一个数异或,所以就变成$0-1\ trie$傻逼题了。

对于子树的情况,跑一下$dfs$序,然后提出$start[x]-1$和$end[x]$两棵线段树求差,然后二分,链的情况直接从上往下做前缀和(这个操作我刚见到的时候$Count\ on\ a\ tree$,我惊呆了,因为我以为要用树链剖分的,但是现在得心应手了)确定$u,v,lca[u,v],fa[lca(u,v)]$四个即可。

14、【BZOJ4137】火星商店问题

$aysn$说有四种写法

  • $cdq$分治套可持久化$01-trie$树
  • 二进制分组套可持久化$01-trie$树
  • 线段树分治套可持久化$01-trie$树
  • $bit$或线段树套$01-trie$树
posted @ 2019-09-11 01:10  HellPix  阅读(186)  评论(0编辑  收藏  举报