CF708D2

D题

题很好,感觉思维得到了升华。把整个题考虑成一个图,对每对$\{i, j\}$,只要tag[i] != tag[j]他们之间就要连边,边权为$|2^i-2^j|$。按照题意,需要找一条边权不断上升的、$\sum|s_i-s_j|$最大的路。由于边权不断上升,可以将边按边权排序(外层$i$从小到大,内层$j$从大到小),然后使用动态规划:dp[i][t]维护只使用前$t$条边时,终点为$i$的路的路径权值最大值。考虑转移,发现$t$增加$1$时只有至多两个dp值会发生变化,因为一步只引入了一条边,而且它只能被加在已经考虑过的路径的末尾。这样,我们可以舍弃$t$维度,而代之以时间维度:$dp$数组只有一维,dp[i]维护当前时刻以$i$结尾的路的路径权值最大值。每当时刻前进1,就新考虑一条边,更新一下dp[i]和dp[j]:$dp_i = \max(dp_i, dp_j + |s_i - s_j|)$和$dp_j=\max(dp_j, dp_i+|s_i-s_j|)$。

区间众数

通用求众数离线做法:离散化之后,开线段树维护数出现的频率的最大值,带单点修改,然后再用莫队,移动区间时就跑一个单点修改,复杂度是$O(n\sqrt{n}\log n)$。

Read More

筛选法建堆

这可能是本学期学习数据结构与算法课的最大收获,就是知道了还有线性建堆的方法。线性建堆可能也是有应用场景的,比如用$O(n)$的空间及时间复杂度,取出前$n/\log n$大的所有数。(?

Read More

BIT在线求第k大数

在做小学期Day5C题(在线维护中位数)时,由于我没有做过,也没有想到正解(对顶堆),卡了很久,最后用一个奇怪的方法做出来了。发现这个奇怪的做法复杂度稍高,但是可以扩展。对顶堆只能维护中位数或固定k的第k大数,而奇怪做法可以(伪?)在线查找第k大数,k可变,代价是$O(\log^2 n)$的,$n$为数列长度。

Read More

day6E

题意

正权无向图$G$,有$n$个点与$m$条边。你要回答$q$次询问,每次询问$u,v$两点,回答对于$u,v$两点,这张图上有多少条边在它们任意一条最短路上出现。

Read More

__builtin_popcount原理

小学期题用了这个函数,觉得十分高级,学习一个。

这个函数用来数二进制数中1的个数。正常的操作是:看unsigned int二进制表示下最右端是不是1;若是1,则计数器+1,再右移;重复32次。这样的操作需要进行32次int运算,效率不够高。这个问题可以二分解决。

Read More

CF630D2F

将每个独立集$V$考虑为原图中被染色的一些顶点,而在原图中加边后$E'$可以得到一个子图$G'$,这个子图如果满足一些条件,$V$就是$E'$生成的子图$G'$中的一个独立集。这些条件为:

  1. 一条边的两端不同时被染色(或$V$中任意两点间没有边)
  2. 没有孤立顶点被染色($V$中的每个点都应当与$E'$中的一条边相连)

Read More

CF620D2E

由于一条路径可以包含一条边多次,所以如果$a$能经历$k$条边到达$b$,那就可以经过$k+2n$条边到达$b$,只需要在路径中随便找一条边不停折返即可。于是考虑对树黑白染色,(注意结论,即树是二分图,从而可以dfs染成黑白两色,方便考虑)。

Read More