集训杂记 6/5
· 6/6
火星人 prefix
好神奇的一道题。
先回忆一下做这个题的时候都出现了哪些问题。
- 首先是一些比较无脑的错误,比如传参的时候传错了,或者是分裂的时候左右点传反了
- 然后就是分析的分裂左右子树的条件错了的问题
- 最后就是这个 \(hash\) 的问题了
哈希的问题挺神奇,就是建点的时候要更新他那个哈希值,因为后面可能会直接调用就不会再更新了。
然后阶段性总结一下平衡树:
- 平衡树维护的是线性区间的数的操作和统计
- 可以像线段树那样维护一段值域,这一定是连续的,因为他会内部进行一个排序。
- 因为父亲节点不是一个抽象出来的代表一个区间的节点,而是一个具体的节点,所以要维护相应的区间的东西的话还需要一定的抽象能力
- 相较于线段树,平衡树可以完成维护较大的值域、插入、删除等操作,并且可以支持由下到上更新,也就是“上传标记”
- 平衡树常数较大
· 6/7
星系探索
做这个题的教训就是:会正确分析时间复杂度真的很重要。
以为暴力求排名很费时间,导致浪费了两个小时瞎想。
概率与期望
- 概率:某事发生的可能在总可能中的占比
\(p[A]\) : \(A\) 的概率
\(p[AB]\) : \(AB\) 同时发生的概率
\(p[A|B]\) : 在 \(B\) 发生时 \(A\) 的概率
全概率公式:
条件概率:
由上可推
贝叶斯公式:
- 期望:一个函数在不同情况下的取值的“调和值”
\(E[f[x]]=\sum_i f[B_i]*p[B_i]\)
妈耶我这个调和值的比喻实在是太恰当了
这个“调和值”就说明了期望的性质实际上跟权值是差不多的
期望的逆推
理解了好半天才明白的。
每一分钟从 \(M\) 个球中随便选出一个球涂成红色并放回,无论所选的球是不是红色。求将所有球涂成红色的时间的期望值。
可以设 \(E[x]\) 表示还有 \(x\) 个球时所需要的期望时间,则有 \(E[M]=0\),要求的就是 \(E[0]\)。
把每一个 \(E[i]\) 拆开来看,他有 \(i/M\) 的概率更新到 \(E[i]\),又有\(1-i/M\)的概率更新到 \(E[i+1]\)。
然后这么逆着推,就有了一种分解期望的方法:\(E[ 更新E[i]的部分 ]\) 和 \(E[ 更新E[i+1]的部分 ]\)。
然后分别计算,两边的权值分别从 \(E[i]\) 和 \(E[i+1]\) 逆推回来,再乘上相应的概率,就有:
这么一个神奇的式子。
概率是什么玩意
太难啦
· 6/8
聪聪和可可
给出一个 \(n\) 个结点的无向图,其中 \(A\) 在 \(M (mouse)\) 点,\(B\) 在 \(C(cat)\) 点,\(A\) 每次向周围或本节点等概率移动一格,而 \(B\) 每次向靠近 \(A\) 的方向移动两格,在每分钟内 \(B\) 先走 \(A\) 再走,求 \(B\) 抓住 \(A\) 所用的期望时间。
首先看到 \(n<=1000\) 就考虑二维 \(dp\) 嘛
然后就知道居然还可以暴力地求出点与点之间的最短距离
打了一个 \(dijistra\) 之后被邢老师点拨之后发现 \(bfs\) 更快
第一次把 \(dp\) 转移式子推正确了
没想到最后还被选择编号较小的点背刺了一刀
守卫者的挑战
\(n\) 次挑战,每次挑战有 \(p_i\) 的概率成功,成功后可以获得一个碎片或者一个有一定容量的背包,只有至少胜利 \(L\) 次并且所有得到的碎片都能用背包装下才算做胜利。求胜利的概率。
注意,因为最多只能获得 \(200\) 个碎片,所以获得的背包大于 \(200\) 的部分直接就不要了。实际容量只是 \(-200\)到\(200\),再都加上个 \(200\) 就能用数组解决该问题了。
蚯蚓排队和这个有异曲同工之妙,都是用不着那么多的东西。
· 6/9
早上过来突然发现自己有了查看oi名字的权限?!
列队春游
有 \(n\) 个小朋友距离为一地站成一排,每个小朋友的视野为他到左边第一个身高大于等于他的小朋友的距离(特别地,第一个小朋友的视野为 \(1\) )。给出 \(n\) 个小朋友的身高,他们随机站,求视野总和的期望。
首先列式子,然后可以发现一个肥肠厉害的转化:
对于每个小朋友而言,设一个 \(p[i]\) 表示这个小朋友视野为\(i\)的概率。
然后要算的就变成了视野大于等于 \(i\) 的概率。
那么设一个 \(k\) 表示比当前这个小朋友高或者等高的人数。
则:
然后对这个式子就可以展开,然后进行一系列的变化,然后就推出了这个式子:
可以推一推,需要用到这个式子:
闲思
正如同那个排队一样,小的在前,大的在后,这是利益最大化;小的在后,大的在前,这是绝对公平。
· 6/10
今天居然真的没有比赛,我哭死
关于dijistra
这两种写法都是正确的:
while(!que.empty()){
int y=que.top().second,cs=que.top().first;
que.pop();
if(dis[x][y]<cs) continue;
for(int i=pre[y];i;i=ed[i].next){
int z=ed[i].e;
if(dis[x][z]>dis[x][y]+w[y][z]){
dis[x][z]=dis[x][y]+w[y][z];
que.push(make_pair(dis[x][z],z));
}
}
}
while(!que.empty()){
int y=que.top().second,cs=que.top().first;
que.pop();
if(vi[y]) continue;
vi[y]=1;
for(int i=pre[y];i;i=ed[i].next){
int z=ed[i].e;
if(dis[x][z]>dis[x][y]+w[y][z]){
dis[x][z]=dis[x][y]+w[y][z];
que.push(make_pair(dis[x][z],z));
}
}
}
其原因就在于每个都保证了当前得到的点的存入队列的 \(dis\) 的确是正确的。
而所以这么写是不对的
while(!que.empty()){
int y=que.top().second,cs=que.top().first;
que.pop();
for(int i=pre[y];i;i=ed[i].next){
int z=ed[i].e;
if(dis[x][z]>dis[x][y]+w[y][z]){
dis[x][z]=dis[x][y]+w[y][z];
if(!vi[z]){
que.push(make_pair(dis[x][z],z));
vi[z]=1;
}
}
}
}
这么写直接就排序错了,输出的不是按真实值排名的点,蓝白点思想出大问题。
· 6/11
概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难概率好难
读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题读不懂题
· 6/12
绿名祭!!!
关于改一个概率期望的式子
\(xuany:\) 我们只需要把这个 \(0.3\) 改成 \(0.4\) 答案就对了
我:但我们对它动手前,需要一个理由
\(Y\_SZ\)(计算中)
我:这个数我见过啊!
\(xuany:\)当初我这个题是暴力 \(+\) 打表过的。
我:?可是这个题是图论 \(+\) 概率啊?
直接震惊我一整年。
好怪,十分里面有七分的那么的怪。
\(xue\) \(wang\) \(gai\) \(lv\) \(qi\) \(dou\) \(gou\) \(bu!!!!\)
今天的考试
\(T_1\) 概率期望题,学了半天还是列不出来,学到了一种
类似于这样的思路↑↑↑↑↑
就是把过去的每一个都加一来达到更新的目的,还可以开一个辅助数组帮助推一下。
\(T_2\) 最后居然打出来了,看起来我对于题目的评估技术还有待于提高。
\(T_3\) 想一想考场上打的应该是正确的,就是没有想到判断那个边界。
不过确实,要是直接求最大值的话不如给每个边长都存一个状态到时候二分。
\(T_4\) 根号分治的背包 \(dp\),那两个数组设的意义就很哇塞。
· 6/14
昨天因为改题谷了一天……
今天没有考试
昨天的考试
\(T_1\) 看着挺吓人,实际上因为是连续的,所以最大连续个数不会超过 \(20\) (\(21!>long\_long\_max\)),同时具有单调性,所以枚举长度二分就好了。
\(T_2\) 一道构造题,不知道要怎么做,希望能找到对应的规律。
\(T_3\) 收获很大的一道题,学会了树状数组上二分和扫描线,对树状数组 \(lowbit\) 有了比较深刻的了解。
\(T_4\) 概率期望🐕都不做
好吧,借上面那个 \(T_4\) 研究一下为什么概率期望大多都是逆推。
首先,应当明确的是无论是正推还是逆推,我们的形如 \(f[x]=p[y]*f[y]+p[z]*f[z]\) 这样的式子中的 \(p[y]、p[z]\) 都是在 \(f[x]\) 中的占比而非普通的概率。
正推的话比较好理解,毕竟这个 \(f[x]\) 里面可以分成若干部分,每一部分分别从前面某一状态转移过来并且概率不同,在 \(f[x]\) 中占的比率也不同。
逆推的可以这么理解:\(f[x]\) 中有一部分有 \(p_i\) 的概率转移到 \(f[y]\),转移部分的权值可以通过 \(f[y]\) 逆推回来,再乘上相应的 \(p_i\) 就对了。
在这个定义下,显然所有 \(p\) 之和应该是 \(1\)。
然后我们就可以发现正推的不足之处:如果直接按他给的概率算的话,这个概率并不是我们要求的占比,相加不为一,还要费劲的导一下,很难。
但是逆推的话,终点的概率必定是一,那么我们直接用这个概率求就行了,很方便。
上面那个 \(T_4\),考场上也是打了一个正推,每次模拟堵塞,然后只得了象征性的 \(43\) 分。
但其实,这不是正逆推的问题。因为这个题末态不确定,只能正推。
我错的原因应该是每次算堵塞的概率,导致算重了多次堵塞。
XOR和路径
给定一个无向连通图,从 \(1\) 开始每次随机选一条路径移动,同时异或上这一条路的权值,到达 \(n\) 点时停止移动。求最后权值的异或和的期望。注意:会有重边和自环。
这道题给出了一个处理类似于异或这种位运算的一种很妙的方法:二进制拆分之后一位一位地算。尤其是像这种异或,每一位之间是互不干扰的。
同时,一开始设的是起点到当前点的期望,但是起点状态不定,所以不行,改设当前点到终点的期望就好了。
· 6/16
昨天状态不好所以又谷了一天
蒲公英
统计区间众数。长度 \(n\leq 40000\),查询次数 \(m\leq 50000\)
分块在不具有加和性区间问题上的区别于线段树等的典型例题。
因为昨天状态烂得跟什么似的所以颓了题解。
解决这个题关键在一个性质:对于区间 \([l,r]\),我们已经处理出了他的一个子区间 \([p,q]\) 的众数 \(w\),那么 \([l,r]\) 的众数候选项只能是 \([p,q]\) 在 \([l,r]\) 中的补集和 \(w\)。
那么,如果我们能够预处理出来每个数出现次数的前缀和,再处理出区间众数,这个问题就很容易了。
但是我们发现,这样的话虽然能O(1)查询,但是预处理的时候复杂度就太高了 \((n^2)\),因为每一个点都要处理,十分繁琐。
然后就是分块大放异彩的时候了。形象地,它把每一个长度为一的块扩展到了 \(\sqrt n\),这样虽然每次要多处理一些边角料,但是省去了相当大的一部分(或许没有那么大?)时间和空间,而它的代价仅仅只是增加了一个几乎可以忽略的 \(O(\sqrt n)\)。
总结一下,线段树这一类的数据结构适于处理具有区间加和性的问题,因为他会通过从更小的区间值较快地 \((O(1))\) 求出较大的区间值,从而完成对区间问题的处理。
但其实分块并没有什么突出的特点适用于不具有加和性的问题,相反地,它只是对处理这个问题的暴力算法进行了优化,而且优化的方法也很暴力。
不信你看:这个题本来暴力的最小区间是 \(1\),求值的时候可以直接 \(O(1)\),但是分块之后就多出了一些边角料。就好比别人在沿着边缘一点一点地剪纸,而我直接先剪出一个简单多边形,再处理剩下的细节。而美妙之处在于,“边角料”不会超过 \(O(\sqrt n)\)。
所以我说,分块是对暴力的暴力优化。
\(p.s:\) \(curly\) 做这个题的时候强制在线煤处理错到 \(si\) 都调不出来望周知。
概率期望 \(dp\) 常设意义
- 该点到 起点/终点/下一个点/某一特定点 的 概率/期望
- 已经多少步/多少距离 的 概率/期望
- 还差多少步/多少距离 的 概率/期望
关于集训结束
今天就放假了,回去补我们那个还剩 \(14.29\%\) 的假期。
这一段时间有不少收获,最重要的是发现打模拟赛真的能收获比刷题更多的东西。期待模拟赛。
完结平衡树开概率期望,完结 ( 其实还差两道黑题和一道状压 \(dp\) 的题 ) 概率期望之后又开了一点分块莫队。
觉得做完分块和状压 \(dp\) 之后可以根据模拟赛学知识点,就是发现有什么新的知识点就学一下刷道例题,然后数学的学习也要推上日程了,感觉这玩意挺重要。
以后就是推知识点,多和大神被灌输交流经验,打一打各种比赛。
没了。