B
平面上有 \(n\) 个点以及 \(k\) 条未知的平行线,每个点都分属一条线,每条线都有至少 \(2\) 点。给出一种方案。
\(n\le 4e4,k\le 50\)。
每个点分属一条线的条件非常重要。考虑利用鸽巢原理。
考虑取出 \(k+1\) 个没有两对点同斜率的点,那么,至少有两个点在一条线上,那么就可以确定斜率。
把在一条线上的其中一个点去掉,剩下 \(k\) 个点一定分属一条线。
取外面一个点出来枚举其接的拿条线确定斜率,如果该斜率是 \(k+1\) 个点两两配对中的某斜率,
检验每个点是否可以在剩下 \(k\) 个点的线上即可。
或者随机 \(i,j\) 作为斜率判断也可以,随机到的概率是 \(O(1/k)\),判断扫一遍即可。
C
求递增的序列个数满足值域 \([1,2^n-1]\),且相邻三个数异或不为 \(0\)。\(n\le 2e7\)。
我们先写出 \(f_{x}\) 表示 \(x\) 结尾的序列个数。\(f_x=1+\sum_{y<x} f_y-[x\otimes y<y]f_{x\otimes y}\).
因为不存在连续 \(4\) 个数相邻三个异或和都是 \(0\),所以 \(f_y\) 直接减掉 \(f_{x\otimes y}\) 的贡献即可。
注意到,根据异或的性质,要减去 \(f_{x\otimes y}\) 的贡献时 \(y,x\) 最高位一定相同。
扣掉 \(x\) 最高位的值设为 \(t_x\),设 \(g_x\) 表示 \(\sum_{x\otimes y<y} f_{x\otimes y}\),容易写出 \(g_x=g_{x-t_x}+g_{t_x}\) 的式子,
边界条件是当 \(x=2^i\) 时,\(g_x=\sum_{y=2^i}^{2^{i+1}-1} f_y\),\(g_0=0\)。
那么 \(f_x=1-g_{t_x}+\sum_{y<x}f_y\)。
这启示我们,对于 \([2^i,2^{i+1}-1]\) 这整段进行转移,不妨设 \(F_i=\sum_{y=2^i}^{2^{i+1}-1} f_y\)。
那么,\(F_i=2^{2i}-1+(2^{2i}-1)\times (\sum_{j<i}F_j)-\sum_{j=1}^{2^i}2^{2^i-j}g_j\)。
诸如 \(2^{2^i-j}\) 这种系数表示被算了多少次。
不妨设 \(G_i=\sum_{j=1}^{2^i-1}2^{2^i-j}g_j\),根据 \(g_x=g_{x-t_x}+g_{t_x}\) 可以写出,\(G_i=(2^i+1)G_{i-1}+(2^i-1)F_{i-1}\)。
那么 \(F_i=(2^{2i}-1)\times (1+\sum_{j<i}F_j)-G_{i}\)。于是 \(F,G\) 递推到 \(n\) 就行了。复杂度 \(O(n)\)。
D
树上每个点一开始有点权,点权每天增加 \(a_i\),每次修改一条边,将 \(a_u\) 加上 \(w\),\(a_v\) 减去 \(w\)。
询问的话询问在某天,\(\min_u(\sum_vdis(u,v)\times a_v)\),即带权重心到所有点加权距离和。
考虑拆贡献到每条边上,即两侧 \(a\) 的和取 \(\min\),这是一次函数的形式,所以只会有一次改变。
而如果有修改的话,由于 \(w\) 是一加一减的,所以只会对一条边有影响,简单修改即可。
只需要把所有改变的时间存进 set 里即可。